* Visual representation of clocked time
@ 2009-11-02 21:16 Gennady Trafimenkov
2009-11-03 17:03 ` Carsten Dominik
0 siblings, 1 reply; 2+ messages in thread
From: Gennady Trafimenkov @ 2009-11-02 21:16 UTC (permalink / raw)
To: emacs-orgmode
Hello everyone,
I was thinking that it would be nice to have a visual representation
of clocked time. It could give you a quick overview of when and how
long you had been working on a particular task.
For example, you have a subtree like this:
** very important task
CLOCK: [2009-10-03 Sat 22:02]--[2009-10-03 Sat 23:21] => 1:19
CLOCK: [2009-10-04 Sun 23:53]--[2009-10-05 Mon 02:10] => 2:17
CLOCK: [2009-10-06 Tue 14:10]--[2009-10-06 Tue 14:50] => 0:40
CLOCK: [2009-10-07 Wed 21:25]--[2009-10-08 Thu 00:21] => 2:56
CLOCK: [2009-10-13 Tue 01:52]--[2009-10-13 Tue 02:52] => 1:00
CLOCK: [2009-10-13 Tue 20:58]--[2009-10-13 Tue 23:32] => 2:34
CLOCK: [2009-10-14 Wed 23:20]--[2009-10-15 Thu 00:55] => 1:35
CLOCK: [2009-10-16 Fri 14:14]--[2009-10-16 Fri 14:53] => 0:39
some text here
You press a combination of keys and get a table like this:
|---------------+-----+-----+-----+-----+-----+-----+-----+------|
| Week Starting | Mon | Tue | Wed | Thu | Fri | Sat | Sun | tt,h |
|---------------+-----+-----+-----+-----+-----+-----+-----+------|
| 2009-09-28 | | | | | | 79 | 137 | 3.6 |
| 2009-10-05 | | 40 | 176 | | | | | 3.6 |
| 2009-10-12 | | 214 | 95 | | 39 | | | 5.8 |
|---------------+-----+-----+-----+-----+-----+-----+-----+------|
The table contains total number of clocked minutes for every day and
total number of hours for every week.
If I could write such a thing in Emacs lisp, I would do that. But
unfortunately I can't. So, I wrote a python script and small function
in lisp to call it. I am posting them here in hope that it might be
useful for someone.
Org-mode is an excellent thing. Thank you!
Best regards,
Gennady Trafimenkov
============================================================
=== ===
============================================================
(defun gt/org-get-clocked-time-stat-on-subtree ()
"Calculate nice table with statistics of clocked time.
It puts results into buffer '*clocked-time-stat*'.
When called with C-u, it copies results into the kill ring.
GNU General Public License version 3 or later."
(interactive)
(let ((outputbuffer "*clocked-time-stat*"))
(save-excursion
(outline-mark-subtree)
(shell-command-on-region (region-beginning) (region-end)
"python ~/bin/create-clock-table.py"
outputbuffer)
(if (equal current-prefix-arg '(4))
(if (get-buffer outputbuffer)
(progn
(with-current-buffer outputbuffer
(mark-whole-buffer)
(kill-new (filter-buffer-substring
(region-beginning) (region-end))))))))))
============================================================
=== create-clock-table.py ==================================
============================================================
#/usr/bin/env python
#
# GNU General Public License version 3 or later
#
# This script extracts all record of this kind from the standart input:
#
# CLOCK: [2009-10-17 Sat 21:47]--[2009-10-17 Sat 23:10] => 1:23
#
# then aggregates data and build table with statistics like this:
# |---------------+-----+-----+-----+-----+-----+-----+-----+------|
# | Week Starting | Mon | Tue | Wed | Thu | Fri | Sat | Sun | Tot. |
# |---------------+-----+-----+-----+-----+-----+-----+-----+------|
# | 2009-08-03 | | | | | | | | 0 |
# | 2009-08-10 | | | | | | | | 0 |
# | 2009-08-17 | | | | 75 | 60 | 60 | 15 | 210 |
# | 2009-08-24 | 75 | 60 | 60 | 70 | | | | 265 |
# | 2009-08-31 | | 10 | | | | | | 10 |
# |---------------+-----+-----+-----+-----+-----+-----+-----+------|
import sys
import re
import datetime
if __name__ == '__main__':
dailyStat = {}
# we are going to extract records like:
# CLOCK: [2009-10-17 Sat 21:47]--[2009-10-17 Sat 23:10] => 1:23
timeExtractor = re.compile('^\s*CLOCK:
\[(\d{4})-(\d\d)-(\d\d).*\]--\[.*\] =>\s+(\d+):(\d\d)')
for line in sys.stdin.readlines():
match = timeExtractor.match(line)
if match:
year, month, day = int(match.group(1)),
int(match.group(2)), int(match.group(3))
hours, minutes = int(match.group(4)), int(match.group(5))
date = datetime.date(year, month, day)
minutes += hours * 60
# print date, minutes
dailyStat.setdefault(date, 0)
dailyStat[date] += minutes
if len(dailyStat) == 0:
sys.exit(0)
minDate = min(dailyStat.keys())
maxDate = max(dailyStat.keys())
firstWeek = minDate - datetime.timedelta(minDate.weekday())
lastWeek = maxDate - datetime.timedelta(maxDate.weekday())
# calculate weekly stat
############################################################
weeklyStat = {}
week = firstWeek
while week <= lastWeek:
weeklyStat[week] = [0, 0, 0, 0, 0, 0, 0, 0]
week += datetime.timedelta(7)
biggestNumber = 0
for day in dailyStat.keys():
weekday = day.weekday()
week = day - datetime.timedelta(weekday)
weeklyStat[week][weekday] = dailyStat[day]
weeklyStat[week][7] += dailyStat[day]
biggestNumber = max(biggestNumber, dailyStat[day])
def PrintTableLine(firstColumn, otherColumns, otherColumnsWidth):
cellTemplate = " %%%ds |" % otherColumnsWidth
line = "| %13s |" % firstColumn
for i in otherColumns:
if i == 0:
line += cellTemplate % ""
else:
line += cellTemplate % i
print line
def PrintTableDelimiter(numOfColumns, otherColumnsWidth):
column = "-" * (otherColumnsWidth + 2)
line = "|" + "-" * (13 + 2)
for i in xrange(1, numOfColumns+1):
line += "+"
line += column
line += "|"
print line
# printing the weekly stat table
############################################################
columnWidth = max(4, len("%d" % biggestNumber) + 1)
PrintTableDelimiter(8, columnWidth)
PrintTableLine("Week Starting", ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
"Sun", "tt,h"], columnWidth)
PrintTableDelimiter(8, columnWidth)
cellTemplate = " %%%ds |" % columnWidth
week = firstWeek
while week <= lastWeek:
# convert total number of minutes in number of hours
weeklyStat[week][7] = "%0.1f" % (float(weeklyStat[week][7]) / 60)
PrintTableLine(week.isoformat(), weeklyStat[week], columnWidth)
week += datetime.timedelta(7)
PrintTableDelimiter(8, columnWidth)
============================================================
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Visual representation of clocked time
2009-11-02 21:16 Visual representation of clocked time Gennady Trafimenkov
@ 2009-11-03 17:03 ` Carsten Dominik
0 siblings, 0 replies; 2+ messages in thread
From: Carsten Dominik @ 2009-11-03 17:03 UTC (permalink / raw)
To: Gennady Trafimenkov; +Cc: emacs-orgmode
Hi Gennady,
thanks for sharing!
- Carsten
On Nov 2, 2009, at 10:16 PM, Gennady Trafimenkov wrote:
> Hello everyone,
>
> I was thinking that it would be nice to have a visual representation
> of clocked time. It could give you a quick overview of when and how
> long you had been working on a particular task.
>
> For example, you have a subtree like this:
>
> ** very important task
> CLOCK: [2009-10-03 Sat 22:02]--[2009-10-03 Sat 23:21] => 1:19
> CLOCK: [2009-10-04 Sun 23:53]--[2009-10-05 Mon 02:10] => 2:17
> CLOCK: [2009-10-06 Tue 14:10]--[2009-10-06 Tue 14:50] => 0:40
> CLOCK: [2009-10-07 Wed 21:25]--[2009-10-08 Thu 00:21] => 2:56
> CLOCK: [2009-10-13 Tue 01:52]--[2009-10-13 Tue 02:52] => 1:00
> CLOCK: [2009-10-13 Tue 20:58]--[2009-10-13 Tue 23:32] => 2:34
> CLOCK: [2009-10-14 Wed 23:20]--[2009-10-15 Thu 00:55] => 1:35
> CLOCK: [2009-10-16 Fri 14:14]--[2009-10-16 Fri 14:53] => 0:39
> some text here
>
> You press a combination of keys and get a table like this:
>
> |---------------+-----+-----+-----+-----+-----+-----+-----+------|
> | Week Starting | Mon | Tue | Wed | Thu | Fri | Sat | Sun | tt,h |
> |---------------+-----+-----+-----+-----+-----+-----+-----+------|
> | 2009-09-28 | | | | | | 79 | 137 | 3.6 |
> | 2009-10-05 | | 40 | 176 | | | | | 3.6 |
> | 2009-10-12 | | 214 | 95 | | 39 | | | 5.8 |
> |---------------+-----+-----+-----+-----+-----+-----+-----+------|
>
> The table contains total number of clocked minutes for every day and
> total number of hours for every week.
>
> If I could write such a thing in Emacs lisp, I would do that. But
> unfortunately I can't. So, I wrote a python script and small function
> in lisp to call it. I am posting them here in hope that it might be
> useful for someone.
>
> Org-mode is an excellent thing. Thank you!
>
> Best regards,
> Gennady Trafimenkov
>
> ============================================================
> === ===
> ============================================================
>
> (defun gt/org-get-clocked-time-stat-on-subtree ()
> "Calculate nice table with statistics of clocked time.
> It puts results into buffer '*clocked-time-stat*'.
> When called with C-u, it copies results into the kill ring.
> GNU General Public License version 3 or later."
> (interactive)
> (let ((outputbuffer "*clocked-time-stat*"))
> (save-excursion
> (outline-mark-subtree)
> (shell-command-on-region (region-beginning) (region-end)
> "python ~/bin/create-clock-table.py"
> outputbuffer)
> (if (equal current-prefix-arg '(4))
> (if (get-buffer outputbuffer)
> (progn
> (with-current-buffer outputbuffer
> (mark-whole-buffer)
> (kill-new (filter-buffer-substring
> (region-beginning) (region-end))))))))))
>
> ============================================================
> === create-clock-table.py ==================================
> ============================================================
>
> #/usr/bin/env python
> #
> # GNU General Public License version 3 or later
> #
> # This script extracts all record of this kind from the standart
> input:
> #
> # CLOCK: [2009-10-17 Sat 21:47]--[2009-10-17 Sat 23:10] => 1:23
> #
> # then aggregates data and build table with statistics like this:
> # |---------------+-----+-----+-----+-----+-----+-----+-----+------|
> # | Week Starting | Mon | Tue | Wed | Thu | Fri | Sat | Sun | Tot. |
> # |---------------+-----+-----+-----+-----+-----+-----+-----+------|
> # | 2009-08-03 | | | | | | | | 0 |
> # | 2009-08-10 | | | | | | | | 0 |
> # | 2009-08-17 | | | | 75 | 60 | 60 | 15 | 210 |
> # | 2009-08-24 | 75 | 60 | 60 | 70 | | | | 265 |
> # | 2009-08-31 | | 10 | | | | | | 10 |
> # |---------------+-----+-----+-----+-----+-----+-----+-----+------|
> import sys
> import re
> import datetime
>
> if __name__ == '__main__':
>
> dailyStat = {}
> # we are going to extract records like:
> # CLOCK: [2009-10-17 Sat 21:47]--[2009-10-17 Sat 23:10] => 1:23
> timeExtractor = re.compile('^\s*CLOCK:
> \[(\d{4})-(\d\d)-(\d\d).*\]--\[.*\] =>\s+(\d+):(\d\d)')
> for line in sys.stdin.readlines():
> match = timeExtractor.match(line)
> if match:
> year, month, day = int(match.group(1)),
> int(match.group(2)), int(match.group(3))
> hours, minutes = int(match.group(4)), int(match.group(5))
> date = datetime.date(year, month, day)
> minutes += hours * 60
> # print date, minutes
>
> dailyStat.setdefault(date, 0)
> dailyStat[date] += minutes
>
> if len(dailyStat) == 0:
> sys.exit(0)
>
> minDate = min(dailyStat.keys())
> maxDate = max(dailyStat.keys())
> firstWeek = minDate - datetime.timedelta(minDate.weekday())
> lastWeek = maxDate - datetime.timedelta(maxDate.weekday())
>
> # calculate weekly stat
> ############################################################
>
> weeklyStat = {}
> week = firstWeek
> while week <= lastWeek:
> weeklyStat[week] = [0, 0, 0, 0, 0, 0, 0, 0]
> week += datetime.timedelta(7)
>
> biggestNumber = 0
> for day in dailyStat.keys():
> weekday = day.weekday()
> week = day - datetime.timedelta(weekday)
> weeklyStat[week][weekday] = dailyStat[day]
> weeklyStat[week][7] += dailyStat[day]
> biggestNumber = max(biggestNumber, dailyStat[day])
>
> def PrintTableLine(firstColumn, otherColumns, otherColumnsWidth):
> cellTemplate = " %%%ds |" % otherColumnsWidth
> line = "| %13s |" % firstColumn
> for i in otherColumns:
> if i == 0:
> line += cellTemplate % ""
> else:
> line += cellTemplate % i
> print line
>
> def PrintTableDelimiter(numOfColumns, otherColumnsWidth):
> column = "-" * (otherColumnsWidth + 2)
> line = "|" + "-" * (13 + 2)
> for i in xrange(1, numOfColumns+1):
> line += "+"
> line += column
> line += "|"
> print line
>
> # printing the weekly stat table
> ############################################################
>
> columnWidth = max(4, len("%d" % biggestNumber) + 1)
> PrintTableDelimiter(8, columnWidth)
> PrintTableLine("Week Starting", ["Mon", "Tue", "Wed", "Thu",
> "Fri", "Sat",
> "Sun", "tt,h"], columnWidth)
> PrintTableDelimiter(8, columnWidth)
> cellTemplate = " %%%ds |" % columnWidth
> week = firstWeek
> while week <= lastWeek:
> # convert total number of minutes in number of hours
> weeklyStat[week][7] = "%0.1f" % (float(weeklyStat[week][7]) /
> 60)
> PrintTableLine(week.isoformat(), weeklyStat[week], columnWidth)
> week += datetime.timedelta(7)
> PrintTableDelimiter(8, columnWidth)
>
> ============================================================
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
- Carsten
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-11-03 17:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-02 21:16 Visual representation of clocked time Gennady Trafimenkov
2009-11-03 17:03 ` Carsten Dominik
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).