Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: my_reviews.py

Issue 9764009: Add median latency to my_reviews.py. Do more calculation on the fly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: fixes Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Get rietveld stats about the review you done, or forgot to do. 6 """Get rietveld stats about the review you done, or forgot to do.
7 7
8 Example: 8 Example:
9 - my_reviews.py -r me@chromium.org -Q for stats for last quarter. 9 - my_reviews.py -r me@chromium.org -Q for stats for last quarter.
10 """ 10 """
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 if seconds > 0 and not out: 54 if seconds > 0 and not out:
55 # Skip seconds unless there's only seconds. 55 # Skip seconds unless there's only seconds.
56 out.append('%02ds' % seconds) 56 out.append('%02ds' % seconds)
57 return prefix + ''.join(out) 57 return prefix + ''.join(out)
58 58
59 59
60 class Stats(object): 60 class Stats(object):
61 def __init__(self): 61 def __init__(self):
62 self.total = 0 62 self.total = 0
63 self.actually_reviewed = 0 63 self.actually_reviewed = 0
64 self.average_latency = 0. 64 self.latencies = []
65 self.number_latency = 0
66 self.lgtms = 0 65 self.lgtms = 0
67 self.multiple_lgtms = 0 66 self.multiple_lgtms = 0
68 self.drive_by = 0 67 self.drive_by = 0
69 self.not_requested = 0 68 self.not_requested = 0
70 self.self_review = 0 69 self.self_review = 0
71 70
72 self.percent_done = 0.
73 self.percent_lgtm = 0. 71 self.percent_lgtm = 0.
74 self.percent_drive_by = 0. 72 self.percent_drive_by = 0.
75 self.percent_not_requested = 0. 73 self.percent_not_requested = 0.
76 self.days = 0 74 self.days = 0
77 self.review_per_day = 0.
78 self.review_done_per_day = 0.
79 75
80 def add_latency(self, latency): 76 @property
81 self.average_latency = ( 77 def average_latency(self):
82 (self.average_latency * self.number_latency + latency) / 78 if not self.latencies:
83 (self.number_latency + 1.)) 79 return 0
84 self.number_latency += 1 80 return sum(self.latencies) / float(len(self.latencies))
81
82 @property
83 def median_latency(self):
84 if not self.latencies:
85 return 0
86 length = len(self.latencies)
87 latencies = sorted(self.latencies)
88 if (length & 1) == 0:
89 return (latencies[length/2] + latencies[length/2+1]) / 2.
90 else:
91 return latencies[length/2]
92
93 @property
94 def percent_done(self):
95 if not self.total:
96 return 0
97 return self.actually_reviewed * 100. / self.total
98
99 @property
100 def review_per_day(self):
101 if not self.days:
102 return 0
103 return self.total * 1. / self.days
104
105 @property
106 def review_done_per_day(self):
107 if not self.days:
108 return 0
109 return self.actually_reviewed * 1. / self.days
85 110
86 def finalize(self, first_day, last_day): 111 def finalize(self, first_day, last_day):
87 if self.total:
88 self.percent_done = (self.actually_reviewed * 100. / self.total)
89 if self.actually_reviewed: 112 if self.actually_reviewed:
90 self.percent_lgtm = (self.lgtms * 100. / self.actually_reviewed) 113 self.percent_lgtm = (self.lgtms * 100. / self.actually_reviewed)
91 self.percent_drive_by = (self.drive_by * 100. / self.actually_reviewed) 114 self.percent_drive_by = (self.drive_by * 100. / self.actually_reviewed)
92 self.percent_not_requested = ( 115 self.percent_not_requested = (
93 self.not_requested * 100. / self.actually_reviewed) 116 self.not_requested * 100. / self.actually_reviewed)
94 if first_day and last_day: 117 if first_day and last_day:
95 self.days = (to_datetime(last_day) - to_datetime(first_day)).days + 1 118 self.days = (to_datetime(last_day) - to_datetime(first_day)).days + 1
96 if self.days:
97 self.review_per_day = self.total * 1. / self.days
98 self.review_done_per_day = self.actually_reviewed * 1. / self.days
99 119
100 120
101 def _process_issue_lgtms(issue, reviewer, stats): 121 def _process_issue_lgtms(issue, reviewer, stats):
102 """Calculates LGTMs stats.""" 122 """Calculates LGTMs stats."""
103 stats.actually_reviewed += 1 123 stats.actually_reviewed += 1
104 reviewer_lgtms = len([ 124 reviewer_lgtms = len([
105 msg for msg in issue['messages'] 125 msg for msg in issue['messages']
106 if msg['approval'] and msg['sender'] == reviewer]) 126 if msg['approval'] and msg['sender'] == reviewer])
107 if reviewer_lgtms > 1: 127 if reviewer_lgtms > 1:
108 stats.multiple_lgtms += 1 128 stats.multiple_lgtms += 1
(...skipping 29 matching lines...) Expand all
138 158
139 if first_msg_from_owner and msg['sender'] == reviewer: 159 if first_msg_from_owner and msg['sender'] == reviewer:
140 delta = msg['date'] - first_msg_from_owner['date'] 160 delta = msg['date'] - first_msg_from_owner['date']
141 latency = delta.seconds + delta.days * 24 * 3600 161 latency = delta.seconds + delta.days * 24 * 3600
142 break 162 break
143 163
144 if latency is None: 164 if latency is None:
145 stats.not_requested += 1 165 stats.not_requested += 1
146 return '<no rqst sent>' 166 return '<no rqst sent>'
147 if latency > 0: 167 if latency > 0:
148 stats.add_latency(latency) 168 stats.latencies.append(latency)
149 else: 169 else:
150 stats.not_requested += 1 170 stats.not_requested += 1
151 return to_time(latency) 171 return to_time(latency)
152 172
153 173
154 def _process_issue(issue): 174 def _process_issue(issue):
155 """Preprocesses the issue to simplify the remaining code.""" 175 """Preprocesses the issue to simplify the remaining code."""
156 issue['owner_email'] = username(issue['owner_email']) 176 issue['owner_email'] = username(issue['owner_email'])
157 issue['reviewers'] = set(username(r) for r in issue['reviewers']) 177 issue['reviewers'] = set(username(r) for r in issue['reviewers'])
158 # By default, hide commit-bot. 178 # By default, hide commit-bot.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 print >> sys.stderr, ( 252 print >> sys.stderr, (
233 '%4d were requested over IM or irc (%5.1f%% of reviews done).' % ( 253 '%4d were requested over IM or irc (%5.1f%% of reviews done).' % (
234 stats.not_requested, stats.percent_not_requested)) 254 stats.not_requested, stats.percent_not_requested))
235 print >> sys.stderr, ( 255 print >> sys.stderr, (
236 ('%4d issues LGTM\'d (%5.1f%% of reviews done),' 256 ('%4d issues LGTM\'d (%5.1f%% of reviews done),'
237 ' gave multiple LGTMs on %d issues.') % ( 257 ' gave multiple LGTMs on %d issues.') % (
238 stats.lgtms, stats.percent_lgtm, stats.multiple_lgtms)) 258 stats.lgtms, stats.percent_lgtm, stats.multiple_lgtms))
239 print >> sys.stderr, ( 259 print >> sys.stderr, (
240 'Average latency from request to first comment is %s.' % 260 'Average latency from request to first comment is %s.' %
241 to_time(stats.average_latency)) 261 to_time(stats.average_latency))
262 print >> sys.stderr, (
263 'Median latency from request to first comment is %s.' %
264 to_time(stats.median_latency))
242 265
243 266
244 def print_count(reviewer, created_after, created_before, instance_url): 267 def print_count(reviewer, created_after, created_before, instance_url):
245 remote = rietveld.Rietveld(instance_url, None, None) 268 remote = rietveld.Rietveld(instance_url, None, None)
246 print len(list(remote.search( 269 print len(list(remote.search(
247 reviewer=reviewer, 270 reviewer=reviewer,
248 created_after=created_after, 271 created_after=created_after,
249 created_before=created_before, 272 created_before=created_before,
250 keys_only=True))) 273 keys_only=True)))
251 274
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 print_reviews( 348 print_reviews(
326 options.reviewer, 349 options.reviewer,
327 options.begin, 350 options.begin,
328 options.end, 351 options.end,
329 options.instance_url) 352 options.instance_url)
330 return 0 353 return 0
331 354
332 355
333 if __name__ == '__main__': 356 if __name__ == '__main__':
334 sys.exit(main()) 357 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698