def chi_sq_edits_per_user_2(user): notes = Note.objects.filter(owner=user) edits_ = ca.note_edits_for_user(notes[0].owner) chiMatrix = r.matrix(c([0 for i in range(14)]), ncol=2,nrow=7) for n in notes: if n.jid in edits_: createdDate = wUtil.msecToDate(n.created) createdDOW = createdDate.weekday() topOfDay = dd.datetime(year=createdDate.year, month=createdDate.month, day=createdDate.day) for edit_action in edits_[n.jid]: timeDelta = wUtil.msecToDate(edit_action['when']) - topOfDay if timeDelta.days >= 7: ## For each edit of this note, find editDOW and increment spot in matrix editDOW = wUtil.msecToDate(edit_action['when']).weekday() if createdDOW == editDOW: chiMatrix[createdDOW] += 1 else: chiMatrix[createdDOW+7] += 1 pass pass pass pass print chiMatrix print '--------------------------------------------' result = r('chisq.test')(chiMatrix,p=r.c(1/7,6/7)) print result print '--------------------------------------------' return result
def chisq_edits_for_users_2(users): chiMatrix = r.matrix(c([0 for i in range(14)]), ncol=2,nrow=7) for user in users: print user.id notes = Note.objects.filter(owner=user) edits_ = ca.note_edits_for_user(user) for n in notes: if n.jid in edits_: createdDOW = wUtil.msecToDate(n.created).weekday() for edit_action in edits_[n.jid]: timeDelta = edit_action['when'] - n.created if timeDelta > 1000*3600*24*7: ## For each edit of this note, find editDOW and increment spot in matrix editDOW = wUtil.msecToDate(edit_action['when']).weekday() if createdDOW == editDOW: chiMatrix[createdDOW] += 1 else: chiMatrix[createdDOW+7] += 1 pass pass pass pass pass pass result = r('chisq.test')(chiMatrix, p=r.c(1/7,6/7)) return (result, chiMatrix)
def mmmPlot(filename, notes, title='title'): global firstBirth ##firstBirth = 1217622560992.0 ## Meta-data for title allLogs = ActivityLog.objects.filter(owner=notes[0].owner, action__in=['note-add','note-delete']) saveLogCount = ActivityLog.objects.filter(owner=notes[0].owner, action='note-save').count() msecToWeek = 1.0/(1000.0*60*60*24*7) msecOfWeek = 1000.0*60*60*24*7 useremail ,noteCount, actionCount = notes[0].owner.email, notes.count(), allLogs.count() title = "#Notes:#SaveLogs:#Dels:Email -- " + str(noteCount) + ":" + str(saveLogCount) + ":" + str(sum([n.deleted for n in notes])) + ":" + useremail ## Meta-data for points points = {'note-add':r.c(), 'note-delete':r.c()} ## Shortened to just the two, since note-edit added later births , deaths = {}, {} today = time.time()*1000.0 r.png(file=cap.make_filename(filename), w=6400,h=3200) ## 3200x1600, 9600x4800, 12.8x6.4 cc=[x['created'] for x in notes.values('created')] dd=allLogs.values('when') minBirth, maxBirth = float(min(cc)), float(max(cc)) ## Week 2011 was first week of listit minAction, maxAction = float(min(dd)['when']), float(max(dd)['when']) for log in allLogs: noteArr = notes.filter(jid=log.noteid) if len(noteArr) < 1: continue note = noteArr[0] births[note.jid] = note.created if not note.deleted and note.jid not in deaths: deaths[note.jid] = today pass if (log.action == 'note-delete'): deaths[note.jid] = float(log.when) points[log.action] = r.rbind(points[log.action],c([float(note.created),float(log.when)])) pass xl,yl="Created Date", "Action Date" r.plot(points['note-add'], cex=2.0,col = "green", pch='o',xlab=xl,ylab=yl, main=title, xlim=r.c(firstBirth, today), ylim=r.c(firstBirth, today), axes=False) xWeeks = [int(x) for x in range(int(firstBirth*msecToWeek), int(time.time()*1000*msecToWeek), 1)] yWeeks = [int(y) for y in range(int(firstBirth*msecToWeek), int(time.time()*1000*msecToWeek), 1)] r.axis(1, at=c([float(x*7*24*60*60*1000.0) for x in xWeeks]), labels=c([int(x)-2012 for x in xWeeks]), tck=1) r.axis(2, at=c([float(y*7*24*60*60*1000.0) for y in yWeeks]), labels=c([int(x)-2012 for x in yWeeks]), tck=1) #New code for edits inserted here edits_ = ca.note_edits_for_user(notes[0].owner) points['note-edit'] = r.c() points['note-searches'] = r.c() edit_dir, edit_delta, edit_col = r.c(), r.c(), r.c() searches = searches_by_note_jid(notes[0].owner) for n in notes: ## wCom: not all notes eval'd here may have note-add events !! if n.jid in edits_: ##print "in ",n.jid,n.owner.email,len(edits_[n.jid]) for edit_action in edits_[n.jid]: ##if edit_categorized( ## Add big icon points['note-edit'] = r.rbind(points['note-edit'],c([float(n.created), float(edit_action['when'])])) edit_dir = r.c(edit_dir, pch_of_delta(edit_action['initial'],edit_action['final'])) edit_delta = r.c(edit_delta, 14)#abs(10 + 10*(len(edit_action['initial']) - len(edit_action['final']))/1000.0)) edit_col = r.c(edit_col, col_of_edit(edit_action['initial'],'outer')) ## Add small icon points['note-edit'] = r.rbind(points['note-edit'],c([float(n.created), float(edit_action['when'])])) edit_dir = r.c(edit_dir, pch_of_innerEdit(edit_action['initial'],edit_action['final'])) edit_delta = r.c(edit_delta, 7)#abs(10 + 10*(len(edit_action['initial']) - len(edit_action['final']))/1000.0)) edit_col = r.c(edit_col, col_of_edit(edit_action['initial'], 'inner', edit_action['when'])) for x in searches.get(str(n.jid), []): print 'searches', x points['note-searches'] = r.rbind(points['note-searches'],c([float(n.created), float(x['when'])])) ##End new code r.points(points['note-searches'], cex=5.0,col = "dark green", pch='o') r.points(points['note-edit'], col=edit_col, pch=edit_dir, cex=edit_delta) r.points(points['note-delete'], cex=5.0,col = "dark red", pch='x') for x in births.keys(): if x in deaths: color = 'green' if (today-deaths[x] < 0.001) else 'black' r.lines(c([float(births[x])]*2),c([float(births[x]),float(deaths[x])]), col=color, lwd=3) pass devoff()
def compareEditsBinWeek(filename, notes, title='Note Lifelines', color_function=one_or_no_url_redblk, YMAG=0.5): allLogs = ActivityLog.objects.filter(owner=notes[0].owner, action__in=['note-add','note-delete']) ##firstBirth = float(min([x[0] for x in notes.values_list('created')])) global firstBirth title = "%s -- %s %s %s " % (title,str(notes.count()),notes[0].owner.email,notes[0].owner.id) ## Meta-data for points points = {'note-add':r.c(), 'note-delete':r.c()} ## Shortened to just the two, since note-edit added later births, deaths = {}, {}, today = time.time()*1000.0 print "saving to %s " % cap.make_filename(filename) r.png(file=cap.make_filename(filename), w=3200,h=1600) ## 3200x1600, 9600x4800, 12.8x6.4 colors=dict([(n.jid,color_function(n)) for n in notes]) ## 7 creation bins, each with 7 edit bins inside ## Each of 49 bins holds entries detailing when edits happen - plot these on line for that bin! creationBins = [[r.c() for i in xrange(7)] for i in xrange(7)] # order notes by creation jids = [id[0] for id in notes.order_by("created").values_list('jid')] jid2idx = dict([(jids[i],i) for i in xrange(len(jids))]) for log in allLogs: noteArr = notes.filter(jid=log.noteid) if len(noteArr) < 1: continue note = noteArr[0] births[note.jid] = jid2idx[note.jid] if not note.deleted and note.jid not in deaths: deaths[note.jid] = today pass if (log.action == 'note-delete'): deaths[note.jid] = float(log.when-note.created) points[log.action] = r.rbind(points[log.action],c([jid2idx[note.jid],float(log.when-note.created)])) pass # compute the edits, compile the colors edits_ = ca.note_edits_for_user(notes[0].owner) points['note-edit'] = r.c() edit_dir, edit_delta, colors_r = r.c(), r.c(), r.c(), ymax = 0 points['bin-edits'] = r.c() weekdayColors = ['red','orange','yellow','green','blue','grey','brown'] edit_col = r.c() maxDelta = 0 for n in notes: ## wCom: not all notes eval'd here may have note-add events !! colors_r = r.c(colors_r,colors[n.jid]) if n.jid in edits_: for edit_action in edits_[n.jid]: ## Add edit to creationBin noteDOW = wUtil.msecToDate(n.created).weekday() editDOW = wUtil.msecToDate(edit_action['when']).weekday() timeDelta = edit_action['when'] - n.created ##if edit_action['when'] != None and edit_action['when'] > firstBirth and edit_action['when'] < ca.DATABASE_SNAPSHOT_TIME: ## Current y-val plots time between edit and creation -- second y-val in comment plots absolute time of edit if timeDelta > 1000*3600*24*7: points['bin-edits'] = r.rbind(points['bin-edits'], c([int(noteDOW*7+editDOW), float(timeDelta)])) maxDelta = max(float(timeDelta), maxDelta) ##KEEP: points['bin-edits'] = r.rbind(points['bin-edits'], c([int(noteDOW*7+editDOW), float(edit_action['when'])]) ) edit_col = r.c(edit_col, weekdayColors[editDOW]) pass xl,yl="Created Date", "Action Date" #maxDelta = 1000*3600*24*60 r.plot(points['bin-edits'], cex=3.0, col=edit_col, pch='x' ,xlab=xl,ylab=yl, main=title, xlim=r.c(0, 48), ylim=c([0, float(maxDelta)]), axes=False ) ##KEEP: , axes=False)#, ylim=c([firstBirth, ca.DATABASE_SNAPSHOT_TIME]) ) ## 1 below, 2 left r.axis(1, at=c(range(0,49,7)), labels=c(['Mon','Tue','Wed','Thur','Fri','Sat','Sun']), col='grey' ) ## Something wrong here #help!# ## Graph is coming up with tiny y-axis plotting # of days between note-create and edit event yTicks, yNames, ySep = [], [], 1000*3600*24 # daily ticks for tickTime in range(0,maxDelta, ySep): # daily ticks yTicks.append(tickTime) yNames.append(float(tickTime)/ySep) pass r.axis(2, at=c(yTicks), labels=c(yNames)) #help!# ##r.points(points['note-edit'], col=colors_r, pch=edit_dir, cex=edit_delta) ##r.points(points['note-delete'], cex=2.0,col = colors_r, pch='x') yWeeks = [int(y) for y in range(int(msecToWeek(firstBirth)), int(msecToWeek(time.time()*1000)), 1)] for x in births.keys(): if x in deaths: stillalive = (today-deaths[x] < 0.001) color = colors[x] # ('green' if stillalive else 'black') ##r.lines( c( [float(births[x])]*2) ,c([ float(births[x]),float(deaths[x]-births[x]) ]), col=color) pass pass for i in range(0,49,7): r.abline(v=float(i)-0.5, col='purple') pass for i in range(0,49): r.abline(v=float(i)-0.5, col='gray') devoff()
def lifelineFlatCollapsedCompareColor(filename, notes, title='Note Lifelines', color_function=black, YMAG=1.0): allLogs = ActivityLog.objects.filter(owner=notes[0].owner, action__in=['note-add','note-save','note-delete']) firstBirth = float(min([x[0] for x in notes.values_list('created')])) title = "%s -- %s %s %s " % (title,str(notes.count()),notes[0].owner.email,notes[0].owner.id) ## Meta-data for points births, deaths = {}, {}, today = time.time()*1000.0 print "saving to %s " % cap.make_filename(filename) r.png(file=cap.make_filename(filename), w=3200,h=1600) ## 3200x1600, 9600x4800, 12.8x6.4 texts=dict([(n.jid,n.contents) for n in notes]) births = dict([(n.jid,float(n.created)) for n in notes]) jid2note = dict([(n.jid,n) for n in notes]) whenmax = 0 whenmin = time.time()*1000.0 for log in allLogs: if log.action == 'note-add': births[log.noteid] = float(log.when) if log.action in ['note-add','note-save'] and log.noteText is not None and log.noteid not in texts : texts[log.noteid] = log.noteText if log.action == 'note-delete': deaths[log.noteid] = float(log.when) whenmax = max(whenmax,float(log.when)) whenmin = min(whenmin,float(log.when)) print "whenmax ", whenmin, '-', int(whenmax), (whenmax-whenmin)/(24*60*60*1000.0) # if not deleted we fill these in for n in notes.filter(deleted=False) : deaths[n.jid] = whenmax # order notes by creation births_ordered = [ (jid, btime) for jid, btime in births.iteritems() ] births_ordered.sort(key=lambda x:x[1]) jid2idx = dict([(births_ordered[i][0],i) for i in xrange(len(births_ordered))]) # compute the edits, compile the colors print "computing edits" edits_ = ca.note_edits_for_user(notes[0].owner) print "Color function" colors=dict([(jid,color_function(text2vals(text))) for jid,text in texts.iteritems()]) print "--" births_r,colors_r,deletes_r= r.c(),r.c(),r.c() edits_r = r.c() edit_dirs_r = r.c() edit_delta = 3 print "BIRTHS= %d " % len(births) print "DEATHS %d " % len(deaths) for njid in births: births_r = r.rbind(births_r, c([ jid2idx[njid], 0 ])) # colors_r = r.c(colors_r,colors[njid] if njid in colors else'grey') deletes_r = r.rbind(deletes_r, c([ jid2idx[njid], deaths[njid]-births[njid] if njid in deaths else whenmax-whenmin ])) # whenmax-whenmin])) if njid in edits_: for edit_action in edits_[njid]: ## Add big icon edits_r = r.rbind(edits_r,c([jid2idx[njid], float(edit_action['when'])-births[njid]])) edit_dirs_r = r.c(edit_dirs_r, pch_of_delta(edit_action['initial'],edit_action['final'])) r.plot(births_r,cex=2.0, col=colors_r, pch='o',xlab='Created date',ylab='Action date', main=title, xlim=r.c(0, notes.count()),ylim=r.c(0, YMAG*(whenmax-whenmin)), axes=False) r.points(edits_r, col='black', pch=edit_dirs_r, cex=edit_delta) r.points(deletes_r, cex=2.0,col = 'black', pch='x') yWeeks = [int(y) for y in range(int(msecToWeek(firstBirth)), int(msecToWeek(whenmax)), 1)] r.axis(2, at=c([float(y*7*24*60*60*1000.0) for y in yWeeks]), labels=c([int(x)-2012 for x in yWeeks]), tck=1) duds = [] for x in births.keys(): if x in deaths and x in colors: r.lines(c([float(jid2idx[x])]*2),c([float(jid2idx[x]),float(deaths[x]-births[x])]), col=colors[x]) else: duds.append(x) print "skipped %d whose death time was not known " % len(duds) goodness_stats = [ ("notes", len(births) ), ("missing note" ,len( [x for x in births if x not in jid2note]) ), ("missing text" ,len([x for x in births if x not in texts])), ("missing note-delete times" , len([jid2note[x].deleted for x in births if x in jid2note and x not in deaths])), ("negative lifetime", len([x for x in births if x in deaths and deaths[x] - births[x] < 0])) ] print "avg start-end %d " % (median( [deaths[njid]-births[njid] for njid in births.keys() if njid in deaths ] )/(24*60*60*1000.0)) devoff() return goodness_stats
def compareEditsBinWeek(filename, notes, title='Note Lifelines', color_function=one_or_no_url_redblk, YMAG=0.5): allLogs = ActivityLog.objects.filter( owner=notes[0].owner, action__in=['note-add', 'note-delete']) ##firstBirth = float(min([x[0] for x in notes.values_list('created')])) global firstBirth title = "%s -- %s %s %s " % (title, str( notes.count()), notes[0].owner.email, notes[0].owner.id) ## Meta-data for points points = { 'note-add': r.c(), 'note-delete': r.c() } ## Shortened to just the two, since note-edit added later births, deaths = {}, {}, today = time.time() * 1000.0 print "saving to %s " % cap.make_filename(filename) r.png(file=cap.make_filename(filename), w=3200, h=1600) ## 3200x1600, 9600x4800, 12.8x6.4 colors = dict([(n.jid, color_function(n)) for n in notes]) ## 7 creation bins, each with 7 edit bins inside ## Each of 49 bins holds entries detailing when edits happen - plot these on line for that bin! creationBins = [[r.c() for i in xrange(7)] for i in xrange(7)] # order notes by creation jids = [id[0] for id in notes.order_by("created").values_list('jid')] jid2idx = dict([(jids[i], i) for i in xrange(len(jids))]) for log in allLogs: noteArr = notes.filter(jid=log.noteid) if len(noteArr) < 1: continue note = noteArr[0] births[note.jid] = jid2idx[note.jid] if not note.deleted and note.jid not in deaths: deaths[note.jid] = today pass if (log.action == 'note-delete'): deaths[note.jid] = float(log.when - note.created) points[log.action] = r.rbind( points[log.action], c([jid2idx[note.jid], float(log.when - note.created)])) pass # compute the edits, compile the colors edits_ = ca.note_edits_for_user(notes[0].owner) points['note-edit'] = r.c() edit_dir, edit_delta, colors_r = r.c(), r.c(), r.c(), ymax = 0 points['bin-edits'] = r.c() weekdayColors = [ 'red', 'orange', 'yellow', 'green', 'blue', 'grey', 'brown' ] edit_col = r.c() maxDelta = 0 for n in notes: ## wCom: not all notes eval'd here may have note-add events !! colors_r = r.c(colors_r, colors[n.jid]) if n.jid in edits_: for edit_action in edits_[n.jid]: ## Add edit to creationBin noteDOW = wUtil.msecToDate(n.created).weekday() editDOW = wUtil.msecToDate(edit_action['when']).weekday() timeDelta = edit_action['when'] - n.created ##if edit_action['when'] != None and edit_action['when'] > firstBirth and edit_action['when'] < ca.DATABASE_SNAPSHOT_TIME: ## Current y-val plots time between edit and creation -- second y-val in comment plots absolute time of edit if timeDelta > 1000 * 3600 * 24 * 7: points['bin-edits'] = r.rbind( points['bin-edits'], c([int(noteDOW * 7 + editDOW), float(timeDelta)])) maxDelta = max(float(timeDelta), maxDelta) ##KEEP: points['bin-edits'] = r.rbind(points['bin-edits'], c([int(noteDOW*7+editDOW), float(edit_action['when'])]) ) edit_col = r.c(edit_col, weekdayColors[editDOW]) pass xl, yl = "Created Date", "Action Date" #maxDelta = 1000*3600*24*60 r.plot(points['bin-edits'], cex=3.0, col=edit_col, pch='x', xlab=xl, ylab=yl, main=title, xlim=r.c(0, 48), ylim=c([0, float(maxDelta)]), axes=False) ##KEEP: , axes=False)#, ylim=c([firstBirth, ca.DATABASE_SNAPSHOT_TIME]) ) ## 1 below, 2 left r.axis(1, at=c(range(0, 49, 7)), labels=c(['Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun']), col='grey') ## Something wrong here #help!# ## Graph is coming up with tiny y-axis plotting # of days between note-create and edit event yTicks, yNames, ySep = [], [], 1000 * 3600 * 24 # daily ticks for tickTime in range(0, maxDelta, ySep): # daily ticks yTicks.append(tickTime) yNames.append(float(tickTime) / ySep) pass r.axis(2, at=c(yTicks), labels=c(yNames)) #help!# ##r.points(points['note-edit'], col=colors_r, pch=edit_dir, cex=edit_delta) ##r.points(points['note-delete'], cex=2.0,col = colors_r, pch='x') yWeeks = [ int(y) for y in range(int(msecToWeek(firstBirth)), int(msecToWeek(time.time() * 1000)), 1) ] for x in births.keys(): if x in deaths: stillalive = (today - deaths[x] < 0.001) color = colors[x] # ('green' if stillalive else 'black') ##r.lines( c( [float(births[x])]*2) ,c([ float(births[x]),float(deaths[x]-births[x]) ]), col=color) pass pass for i in range(0, 49, 7): r.abline(v=float(i) - 0.5, col='purple') pass for i in range(0, 49): r.abline(v=float(i) - 0.5, col='gray') devoff()
def mmmPlot(filename, notes, title='title'): global firstBirth ##firstBirth = 1217622560992.0 ## Meta-data for title allLogs = ActivityLog.objects.filter( owner=notes[0].owner, action__in=['note-add', 'note-delete']) saveLogCount = ActivityLog.objects.filter(owner=notes[0].owner, action='note-save').count() msecToWeek = 1.0 / (1000.0 * 60 * 60 * 24 * 7) msecOfWeek = 1000.0 * 60 * 60 * 24 * 7 useremail, noteCount, actionCount = notes[0].owner.email, notes.count( ), allLogs.count() title = "#Notes:#SaveLogs:#Dels:Email -- " + str(noteCount) + ":" + str( saveLogCount) + ":" + str(sum([n.deleted for n in notes])) + ":" + useremail ## Meta-data for points points = { 'note-add': r.c(), 'note-delete': r.c() } ## Shortened to just the two, since note-edit added later births, deaths = {}, {} today = time.time() * 1000.0 r.png(file=cap.make_filename(filename), w=6400, h=3200) ## 3200x1600, 9600x4800, 12.8x6.4 cc = [x['created'] for x in notes.values('created')] dd = allLogs.values('when') minBirth, maxBirth = float(min(cc)), float( max(cc)) ## Week 2011 was first week of listit minAction, maxAction = float(min(dd)['when']), float(max(dd)['when']) for log in allLogs: noteArr = notes.filter(jid=log.noteid) if len(noteArr) < 1: continue note = noteArr[0] births[note.jid] = note.created if not note.deleted and note.jid not in deaths: deaths[note.jid] = today pass if (log.action == 'note-delete'): deaths[note.jid] = float(log.when) points[log.action] = r.rbind(points[log.action], c([float(note.created), float(log.when)])) pass xl, yl = "Created Date", "Action Date" r.plot(points['note-add'], cex=2.0, col="green", pch='o', xlab=xl, ylab=yl, main=title, xlim=r.c(firstBirth, today), ylim=r.c(firstBirth, today), axes=False) xWeeks = [ int(x) for x in range(int(firstBirth * msecToWeek), int(time.time() * 1000 * msecToWeek), 1) ] yWeeks = [ int(y) for y in range(int(firstBirth * msecToWeek), int(time.time() * 1000 * msecToWeek), 1) ] r.axis(1, at=c([float(x * 7 * 24 * 60 * 60 * 1000.0) for x in xWeeks]), labels=c([int(x) - 2012 for x in xWeeks]), tck=1) r.axis(2, at=c([float(y * 7 * 24 * 60 * 60 * 1000.0) for y in yWeeks]), labels=c([int(x) - 2012 for x in yWeeks]), tck=1) #New code for edits inserted here edits_ = ca.note_edits_for_user(notes[0].owner) points['note-edit'] = r.c() points['note-searches'] = r.c() edit_dir, edit_delta, edit_col = r.c(), r.c(), r.c() searches = searches_by_note_jid(notes[0].owner) for n in notes: ## wCom: not all notes eval'd here may have note-add events !! if n.jid in edits_: ##print "in ",n.jid,n.owner.email,len(edits_[n.jid]) for edit_action in edits_[n.jid]: ##if edit_categorized( ## Add big icon points['note-edit'] = r.rbind( points['note-edit'], c([float(n.created), float(edit_action['when'])])) edit_dir = r.c( edit_dir, pch_of_delta(edit_action['initial'], edit_action['final'])) edit_delta = r.c( edit_delta, 14 ) #abs(10 + 10*(len(edit_action['initial']) - len(edit_action['final']))/1000.0)) edit_col = r.c(edit_col, col_of_edit(edit_action['initial'], 'outer')) ## Add small icon points['note-edit'] = r.rbind( points['note-edit'], c([float(n.created), float(edit_action['when'])])) edit_dir = r.c( edit_dir, pch_of_innerEdit(edit_action['initial'], edit_action['final'])) edit_delta = r.c( edit_delta, 7 ) #abs(10 + 10*(len(edit_action['initial']) - len(edit_action['final']))/1000.0)) edit_col = r.c( edit_col, col_of_edit(edit_action['initial'], 'inner', edit_action['when'])) for x in searches.get(str(n.jid), []): print 'searches', x points['note-searches'] = r.rbind( points['note-searches'], c([float(n.created), float(x['when'])])) ##End new code r.points(points['note-searches'], cex=5.0, col="dark green", pch='o') r.points(points['note-edit'], col=edit_col, pch=edit_dir, cex=edit_delta) r.points(points['note-delete'], cex=5.0, col="dark red", pch='x') for x in births.keys(): if x in deaths: color = 'green' if (today - deaths[x] < 0.001) else 'black' r.lines(c([float(births[x])] * 2), c([float(births[x]), float(deaths[x])]), col=color, lwd=3) pass devoff()
def lifelineFlatCollapsedCompareColor(filename, notes, title='Note Lifelines', color_function=black, YMAG=1.0): allLogs = ActivityLog.objects.filter( owner=notes[0].owner, action__in=['note-add', 'note-save', 'note-delete']) firstBirth = float(min([x[0] for x in notes.values_list('created')])) title = "%s -- %s %s %s " % (title, str( notes.count()), notes[0].owner.email, notes[0].owner.id) ## Meta-data for points births, deaths = {}, {}, today = time.time() * 1000.0 print "saving to %s " % cap.make_filename(filename) r.png(file=cap.make_filename(filename), w=3200, h=1600) ## 3200x1600, 9600x4800, 12.8x6.4 texts = dict([(n.jid, n.contents) for n in notes]) births = dict([(n.jid, float(n.created)) for n in notes]) jid2note = dict([(n.jid, n) for n in notes]) whenmax = 0 whenmin = time.time() * 1000.0 for log in allLogs: if log.action == 'note-add': births[log.noteid] = float(log.when) if log.action in [ 'note-add', 'note-save' ] and log.noteText is not None and log.noteid not in texts: texts[log.noteid] = log.noteText if log.action == 'note-delete': deaths[log.noteid] = float(log.when) whenmax = max(whenmax, float(log.when)) whenmin = min(whenmin, float(log.when)) print "whenmax ", whenmin, '-', int( whenmax), (whenmax - whenmin) / (24 * 60 * 60 * 1000.0) # if not deleted we fill these in for n in notes.filter(deleted=False): deaths[n.jid] = whenmax # order notes by creation births_ordered = [(jid, btime) for jid, btime in births.iteritems()] births_ordered.sort(key=lambda x: x[1]) jid2idx = dict([(births_ordered[i][0], i) for i in xrange(len(births_ordered))]) # compute the edits, compile the colors print "computing edits" edits_ = ca.note_edits_for_user(notes[0].owner) print "Color function" colors = dict([(jid, color_function(text2vals(text))) for jid, text in texts.iteritems()]) print "--" births_r, colors_r, deletes_r = r.c(), r.c(), r.c() edits_r = r.c() edit_dirs_r = r.c() edit_delta = 3 print "BIRTHS= %d " % len(births) print "DEATHS %d " % len(deaths) for njid in births: births_r = r.rbind(births_r, c([jid2idx[njid], 0])) # colors_r = r.c(colors_r, colors[njid] if njid in colors else 'grey') deletes_r = r.rbind( deletes_r, c([ jid2idx[njid], deaths[njid] - births[njid] if njid in deaths else whenmax - whenmin ])) # whenmax-whenmin])) if njid in edits_: for edit_action in edits_[njid]: ## Add big icon edits_r = r.rbind( edits_r, c([ jid2idx[njid], float(edit_action['when']) - births[njid] ])) edit_dirs_r = r.c( edit_dirs_r, pch_of_delta(edit_action['initial'], edit_action['final'])) r.plot(births_r, cex=2.0, col=colors_r, pch='o', xlab='Created date', ylab='Action date', main=title, xlim=r.c(0, notes.count()), ylim=r.c(0, YMAG * (whenmax - whenmin)), axes=False) r.points(edits_r, col='black', pch=edit_dirs_r, cex=edit_delta) r.points(deletes_r, cex=2.0, col='black', pch='x') yWeeks = [ int(y) for y in range(int(msecToWeek(firstBirth)), int(msecToWeek(whenmax)), 1) ] r.axis(2, at=c([float(y * 7 * 24 * 60 * 60 * 1000.0) for y in yWeeks]), labels=c([int(x) - 2012 for x in yWeeks]), tck=1) duds = [] for x in births.keys(): if x in deaths and x in colors: r.lines(c([float(jid2idx[x])] * 2), c([float(jid2idx[x]), float(deaths[x] - births[x])]), col=colors[x]) else: duds.append(x) print "skipped %d whose death time was not known " % len(duds) goodness_stats = [ ("notes", len(births)), ("missing note", len([x for x in births if x not in jid2note])), ("missing text", len([x for x in births if x not in texts])), ("missing note-delete times", len([ jid2note[x].deleted for x in births if x in jid2note and x not in deaths ])), ("negative lifetime", len([x for x in births if x in deaths and deaths[x] - births[x] < 0])) ] print "avg start-end %d " % (median([ deaths[njid] - births[njid] for njid in births.keys() if njid in deaths ]) / (24 * 60 * 60 * 1000.0)) devoff() return goodness_stats