Skip to content

Instantly share code, notes, and snippets.

@josephcc
Created May 15, 2014 04:41
Show Gist options
  • Select an option

  • Save josephcc/6cf1a1c254a07f1c4b9d to your computer and use it in GitHub Desktop.

Select an option

Save josephcc/6cf1a1c254a07f1c4b9d to your computer and use it in GitHub Desktop.
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
#
#
current_stage = 1
clips = null
id2idx = null
all_keywords = []
final_labels = []
textToHtml = (text, keywords) ->
out = ''
for token in text
term = cleanTerm(token)
if keywords.indexOf(term) >= 0
out += '<span class="token keyword">' + token + '</span> '
else
if keywords.length == 0
out += '<span class="token">' + token + '</span> '
else
out += token + ' '
return out
loadRandomSeeds = (targets) ->
clusters = $('.cluster')
seeds = []
for cluster in clusters
id = $(cluster).attr('data-cluster-id')
if id
seeds.push id
for cluster in targets
$(cluster).children('.seed').html()
id = $(cluster).attr('data-cluster-id')
if id
index = seeds.indexOf(id)
seeds.splice(index, 1)
$(cluster).removeAttr('data-cluster-id')
for cluster in targets
seed = Math.random() * clips.length
seed = Math.round(seed)
if seeds.indexOf(seed) >= 0
continue
seeds.push seed
clip = clips[seed]
$(cluster).children('.seed').html(textToHtml(clip['text'], []))
$(cluster).attr('data-cluster-id', clip['id'])
$(cluster).children('.list').html('')
get_tf_score = (clip, terms) ->
_score = 0
for term in terms
score = clip['terms'][term]
if score?
score = score[0]
else
score = 0
_score += score
score = _score / terms.length
cleanTerm = (term) ->
term = term.replace(/^[^\w]+/gi, '').toLowerCase()
term = term.replace(/[^\w]+$/gi, '').toLowerCase()
term = term.replace(/'s$/gi, '').toLowerCase()
term = term.replace(/’s$/gi, '').toLowerCase()
return term
cleanTerms = (terms) ->
_terms = []
for term in terms
_terms.push cleanTerm(term)
terms = _terms
similar_ranker = (clip_idx, terms, similarity, clips) ->
_ranker = (x, y) ->
# x-y # small -> large
# y-x # large -> small
tx = get_tf_score(clips[x], terms)
ty = get_tf_score(clips[y], terms)
if ty - tx != 0
return ty - tx
else
return similarity[y] - similarity[x]
return _ranker
bindClipEvents = () ->
$('.add-clip').live 'click', (e) ->
console.log 'add-clip clicked'
e.preventDefault
if $('.workspace').hasClass('inactive-this')
alert 'Please read the instructions and click the Start button before you start.'
return
if $(this).hasClass('add-clip-disabled')
$(this).parent().children().addClass('add-clip-disabled')
$(this).removeClass('add-clip-disabled')
else
$(this).addClass('add-clip-disabled')
bindSeedEvents = () ->
$('.clip.seed .token').live 'click', (e) ->
console.log 'token clicked'
e.preventDefault
if $('.workspace').hasClass('inactive-this')
alert 'Please read the instructions and click the Start button before you start.'
return
if $(this).parent().hasClass('inactive-seed')
return
if current_stage < 2
return
term = $(this).text()
term = cleanTerm(term)
console.log term
console.log all_keywords
console.log $.inArray(term, all_keywords)
if (not $(this).hasClass('keyword')) and all_keywords.indexOf(term) >= 0
if current_stage < 3
alert 'Please select unique keywords, request another clip if necessary.'
else
alert 'This keyword is already used in one of the seed clips.'
return
$(this).toggleClass('keyword')
if $(this).hasClass('keyword')
all_keywords.push term
else
all_keywords.splice all_keywords.indexOf(term), 1
console.log all_keywords
if current_stage < 3
return
searchClips($(this).parent().parent())
$('.inactive-seed').live 'click', (e) ->
e.preventDefault
if $('.workspace').hasClass('inactive-this')
alert 'Please read the instructions and click the Start button before you start.'
return
#TODO: remember to persist before leaving this stage
list = $('.clip_list').html()
$('.clip.seed:not(.inactive-seed)').parent().children('.list').html(list)
$('.clip.seed').addClass('inactive-seed')
$(this).removeClass('inactive-seed')
list = $(this).parent().children('.list').html()
$('.clip_list').html(list)
$('.seed_tabs').scrollTo($(this))
$('.clip_list').scrollTop(0)
searchClips = (cluster) ->
keywords = cluster.children('.clip.seed').children('.token.keyword')
console.log keywords
if keywords.length == 0
$(cluster).children('.list').html('')
$('.clip_list').html('')
return
console.log 'continued'
terms = []
for keyword in keywords
terms.push $(keyword).html()
terms = cleanTerms(terms)
id = cluster.attr('data-cluster-id')
clip_idx = id2idx[id]
clip = clips[clip_idx]
idxs = for i in [0...clips.length]
i
idxs.sort(similar_ranker(clip_idx, terms, clip['similarity'], clips))
html = ''
for idx in idxs.slice(0, 10)
if idx == clip_idx
continue
similarity = clip['similarity'][idx]
score = get_tf_score(clips[idx], terms)
tfs = []
for term in terms
tfs.push [term, get_tf_score(clips[idx], [term])]
stats = 'score:' + score.toFixed(4) + ' sim:' + similarity.toFixed(4) + '<br>'
for tf in tfs
stats += '"' + tf[0] + '":' + tf[1].toFixed(2) + ' '
stats = '<div class="stats col-xs-6">' + stats + '</div>'
stats = '<div class="row"><div class="col-xs-6 add-clip-container"><i class="add-clip add-clip-disabled fa fa-check"><a href="#">similar solution</a></i> <i class="add-clip add-clip-disabled fa fa-times"><a href="#">different solution</a></i></div>' + stats + '</div>'
_html = textToHtml(clips[idx]['text'], terms)
html += '<div class="clip" data-cluster-id="' + clips[idx]['id'] + '">' + stats + _html + '</div><hr>'
$(cluster).children('.list').html(html)
$('.clip_list').html(html)
updateStage = () ->
if current_stage > 2
return
$('.stage').hide()
$('.stage-'+current_stage).show()
h = $(window).height()
h = h - $('.header').height()
$('.clips').css('height', h)
$('.clusters').css('height', h)
canContinue = (stage) ->
if stage == 2
_clips = $('.clip.seed')
for _clip in _clips
highlights = $(_clip).children('.token.keyword')
count = highlights.length
if count == 0 or count > 3
alert 'Please highlight one to three keywords in each clip'
return false
return true
if stage == 3
list = $('.clip_list').html()
$('.clip.seed:not(.inactive-seed)').parent().children('.list').html(list)
final_labels = []
clusters = $('.cluster')
for cluster in clusters
cluster = $(cluster)
positive = []
negative = []
seed = cluster.children('.clip.seed')
seed_id = parseInt(cluster.attr('data-cluster-id'))
highlights = seed.children('.token.keyword')
highlights = (cleanTerm($(highlight).text()) for highlight in highlights)
console.log cluster.attr('data-cluster-id')
console.log highlights
console.log '-----------'
_clips = cluster.children('.list').children('.clip')
for _clip in _clips
_clip = $(_clip)
console.log _clip
_clip_id = parseInt(_clip.attr('data-cluster-id'))
control = _clip.children('.row').children('.add-clip-container')
console.log control
label = control.children('i.add-clip:not(.add-clip-disabled)')
if label.length == 0
alert 'Please label all clips searched with all four seed clips on the left.'
return false
console.log 'clip tagged'
label = $(label[0])
if label.hasClass('fa-check')
positive.push _clip_id
else
negative.push _clip_id
final_labels.push {'seed': seed_id, 'positive': positive, 'negative': negative, 'keywords': highlights}
console.log final_labels
return true
# default bypass
return true
jQuery ->
if not jQuery('body').hasClass('v-option-manager-2')
return
$('.dot').live 'click', (e) ->
console.log 'dot clicked'
e.preventDefault
$(this).parent().children('.dot').removeClass('fa-circle')
$(this).parent().children('.dot').addClass('fa-circle-o')
$(this).removeClass('fa-circle-o')
$(this).addClass('fa-circle')
cid = $(this).attr('data-cid')
$(this).parent().parent().parent().find('.cluster-clips .clip').hide()
$(this).parent().parent().parent().find('.cluster-clips .clip[data-cid="' + cid + '"]').show()
console.log $(this)
$('.dot:nth-child(1)').click()
$('.clips').sortable
connectWith: '.cluster-clips'
items: "> .clip.draggable"
appendTo: 'body'
cursor: "move"
helper: 'clone'
containment: 'window'
zIndex: 9999999
tolerance: "pointer"
start: (event, ui) ->
console.log 'start'
$('.cluster-clips .clip').css('opacity', '0.35')
stop: (event, ui) ->
console.log 'start'
$('.cluster-clips .clip').css('opacity', '1.0')
$('.cluster-clips').sortable
connectWith: '.clips, .cluster-clips'
items: "> .clip.draggable"
cursor: "move"
appendTo: 'body'
helper: 'clone'
appendTo: 'body'
containment: 'window'
tolerance: "pointer"
zIndex: 9999999
receive: (event, ui) ->
cid = ui.item.attr('data-cid')
console.log cid
$(this).parent().find('.selector').append('<i class="fa fa-circle-o dot draggable" data-cid="' + cid + '"></i>')
$(this).parent().find('.selector .dot[data-cid="' + cid + '"]').click()
remove: (event, ui) ->
cid = ui.item.attr('data-cid')
console.log cid
$(this).parent().find('.selector .dot[data-cid="' + cid + '"]').remove()
$(this).parent().find('.selector .dot:nth-child(1)').click()
start: (event, ui) ->
console.log 'start'
$('.cluster-clips .clip').css('opacity', '0.35')
$('.clips .clip').css('opacity', '0.75')
$('.clips').addClass('drop-zone')
stop: (event, ui) ->
console.log 'start'
$('.cluster-clips .clip').css('opacity', '1.0')
$('.clips .clip').css('opacity', '1.0')
$('.clips').removeClass('drop-zone')
updateStage()
$('.next-stage').hide()
$('.next').hide()
$('.start-stage').click (e) ->
console.log 'start clicked'
e.preventDefault
$('.next-stage').show()
$('.workspace').removeClass('inactive-this')
$(this).hide()
$('.next').click (e) ->
console.log 'next clicked'
e.preventDefault
if $('.workspace').hasClass('inactive-this')
alert 'Please read the instructions and click the Start button before you start.'
return
target = $($(this).parent().parent())
loadRandomSeeds(target)
$('.next-stage').click (e) ->
e.preventDefault
if not canContinue(current_stage)
return
$('.start-stage').show()
$('.next-stage').hide()
current_stage += 1
console.log 'current stage is ' + current_stage
if current_stage == 3
for cluster in $('.cluster')
searchClips($(cluster))
if current_stage > 3
url = '/feedback/question/' + ka.current.question_id + '/option_manager?labels=' + JSON.stringify(final_labels) + '&' + aws_params
console.log url
window.location = url
updateStage()
$('.workspace').addClass('inactive-this')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment