Skip to content

Instantly share code, notes, and snippets.

@Wizek
Last active May 14, 2016 09:38
Show Gist options
  • Save Wizek/d35c16ec23bff0dd2fb1 to your computer and use it in GitHub Desktop.
Save Wizek/d35c16ec23bff0dd2fb1 to your computer and use it in GitHub Desktop.
Advanced Pro-Con Decision helper for WorkFlowy; decision, workflowy, score summary, hierarchical data binding, searches for matching {{ decisionCount(children) }}, with radius and confidence%
// ==UserScript==
// @name Advanced Pro-Con Decision helper for WorkFlowy
// @description If you write `{{ decisionCount(children) }}` somewhere, this script will sum up `(+)`s, `(-)`s `(+2.3)`s and similar in all children, helping you weigh pros vs cons.
// @match https://workflowy.com/*
// @version v0.3.1
// @grant none
// @namespace https://gist.github.com/Wizek/d35c16ec23bff0dd2fb1
// @downloadURL https://gist.github.com/Wizek/d35c16ec23bff0dd2fb1/raw/decision.user.js
// @require https://cdnjs.cloudflare.com/ajax/libs/ramda/0.17.1/ramda.min.js
// @author Milan Nagy
// ==/UserScript==
// jshint asi:true
"use strict";
var E = {}
E.proc = function (a) {
// TODO Implement
return R.pipe(R.identity(a))
}
setInterval(function(){
var unboundSlice = Array.prototype.slice
var slice = Function.prototype.call.bind(unboundSlice)
var targets = R.pipe(slice, R.filter(R.pipe(R.curryN(1, $), R.invoker(0, 'text'), R.match(/{{\s*decisionCount\(children\)\s*}}/), R.prop('length'))))($('.content'))
//debugger
function processTarget (target) {
target = $(target)
var nameEl = target.find(' > .name > .content');
var isClosed = '.project:not(.open, .task)'
if (target.is(isClosed) || target.find(isClosed).length) {
result = "Error: Closed children"
} else {
var matches = target.text().match(/\([-+]\d*(\.\d+)?\)/g)
var QMatches = target.text().match(/\(\?+\)/g)
var QCount = QMatches
? R.pipe(R.join(''), R.filter(R.equals('?')), R.prop('length'))(QMatches)
: 0
var numbers = (matches || []).map(parseDecisionVector)
var sum = R.reduce(function(memo, num){ return memo + num; }, 0)
var total = sum(numbers)
var round = R.pipe(R.multiply(1000), Math.round, R.divide(R.__, 1000))
var absNums = R.map(Math.abs, numbers)
var radius = sum(absNums)
var f = round
var QString = QCount
? ' Qs: ' + QCount
: ''
var conf = Math.abs(total*100)/radius
var confP = Math.round(conf) + '%'
var eConfP = Math.round(100 - conf) + '%'
var yesNo = (total > 0 ? 'Yes' : 'No' ) + ". " + confP
var answer = conf > 50
? yesNo
: "Doesn't matter, either are good choices. " + eConfP + " Slightly leaning towards " + yesNo
var result
= answer
+ ' (score: ' + f(total)
+ ' confidence-in-choice: ' + confP
+ ' equally-good-choices: ' + eConfP
+ ' radius: ' + f(radius)
+ QString
+ ')'
}
var oldVal = nameEl.text()
var newVal = oldVal.replace(/{{\s*decisionCount\(children\)\s*}}.*/, '{{ decisionCount(children) }} = ' + result)
if (oldVal != newVal) {
nameEl.text(newVal)
}
}
function parseDecisionVector (i) {
var match
if (typeof i == "number") { return i }
if (i == "(+)") { return 1 }
if (i == "(-)") { return -1 }
if (match = i.match(/^\((.*)\)$/)) { return parseFloat(match[1], 10) }
return i
}
R.map(processTarget, slice($(targets).parent().parent()))
}, 2000)
@Wizek
Copy link
Author

Wizek commented Aug 22, 2015

TODOs

  • works!
  • Handles closed children
  • calculates confidence %
  • make it work with greasemonkey/tampermonkey
    • figure out a way to load ramda dependency
  • Readme, description on what this does, how to use it.
  • Implement n-way decision tree support
  • profile cpu
    • Optimize for low CPU and RAM footprint.

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