一个简单的git小时跟踪程序
hourl的Python项目详细描述
%load_extautoreload%autoreload2
每小时
一个简单的git项目小时跟踪程序。hourly
分析提交消息中的“时钟输入/输出”关键字,并使用它们的unix时间戳精确计算工作时间。
开始
安装
pip install hourly
要求
pandas
gitpython
使用量
每小时都会寻找打卡的关键词。
打卡:
git commit -m "clock in - starting work on new feature"
照常做事,然后打卡
git commit -m "clock out - finished feature"
教程
我们可以说明如何在每小时回购本身上使用每小时回购。
git clone https://github.com/asherp/hourly.git
cd hourly
fromhourly.hourlyimportget_work_commits,get_labor,get_earnings
get_work_commits
将所有提交收集到pandas数组中
work=get_work_commits('.')work
c:\programdata\miniconda2\lib\site-packages\pandas\core\sorting.py:257: FutureWarning: Converting timezone-aware DatetimeArray to timezone-naive ndarray with 'datetime64[ns]' dtype. In the future, this will return an ndarray with 'object' dtype where each element is a 'pandas.Timestamp' with the correct 'tz'.
To accept the future behavior, pass 'dtype=object'.
To keep the old behavior, pass 'dtype="datetime64[ns]"'.
items = np.asanyarray(items)
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
message | hash | |
---|---|---|
time | ||
2018-10-19 23:40:41-04:00 | Initial commit | ef5690543bfb354b9325d1fbd1f9abbafbb4d9a4 |
2018-10-19 23:57:48-04:00 | clock in | 5c8f05b57b739ec525291c248ea9200651b49997 |
2018-10-20 00:21:40-04:00 | preparing setup.py | 254ecdacb52fc70bc358f8d55be58df3b70c7609 |
2018-10-20 00:39:11-04:00 | clock out - work done for the day | 0e33fa3d74f663f954b05dd9f30e0128ca7af162 |
2018-10-20 01:06:08-04:00 | clock in - start adding requirements and examp... | dc065b17337b14c2f8e0458de61e6880a338d6ae |
2018-10-20 01:47:01-04:00 | clock out | 644ad6ebf4c9015fd512ed47b858602d784d6204 |
2018-10-20 01:47:45-04:00 | clock in - pro bono | e6b5f78daa68e3731f82effccb66fd4bd14996bf |
2018-10-20 01:51:36-04:00 | clock out - pro bono | 1aff88af5e9688645966ccd15da8e1530205cfea |
2018-10-20 02:03:56-04:00 | clock in - finishing tutorial | 53bd7316e579d8582c46af09277b40fbba3a390e |
2018-10-20 02:11:54-04:00 | clock out - converted notebook for README | d55b5718a3178ab6161f7e3a148c6561a305cd79 |
2018-10-20 02:14:21-04:00 | had to clock out so notebook examples don't break | d9ec537b36475b565df6b28d0cab6edc3a89f2da |
2018-10-20 02:18:27-04:00 | fixed for rendering | e2f8a2ca212fa9e7568618934da18a0ec7164fa3 |
2018-10-20 02:22:56-04:00 | fixing requiremens that raised a security alert | e0e71a05c6c5af1fc5515040ec75f33b71bd3b15 |
2018-10-20 02:51:13-04:00 | fixed requirements, tutorial updates | d8d87767005022c9a8e83015d40f6fb736f2b73b |
2018-10-20 02:57:22-04:00 | merging | f5585c89612a5fac2d948ee61536fffe276f8949 |
2018-10-20 03:24:58-04:00 | Remove autoreload | b2c1d8677ea57aeb959350d663475ba3077f2c96 |
2018-10-20 11:53:00-04:00 | clock in - handling errant messages | fa615994ba6b771594d711dea6087cc7ba0348b5 |
2018-10-20 13:16:13-04:00 | clock out - converting to pd.Timestamp | ed7aab29e43e7120428816481216198a255de8f4 |
2018-10-20 13:47:56-04:00 | clock in - adding work log | 5b398037bf24cd503a7fc88c3b078913fa184f7e |
2018-10-20 14:33:35-04:00 | clock out - see WorkLog.md | 93c2aa04aeba7cfe1573205abec053c7da9e9864 |
2018-10-20 14:35:58-04:00 | merged | 6a7f4ac45de70d94fb943d0676265cafd5bf1e41 |
2018-10-20 17:34:38-04:00 | pushing version | 2b633644d6ba24b9c1bbff6881a99df6ab935a8d |
2018-10-28 13:44:48-04:00 | clock in | c4e95f59dc0c8ce296a40300760ab68800f7e139 |
2018-10-28 13:56:35-04:00 | clock out | f5200e718c062e828d436506286fd05e56b606c5 |
2018-11-23 13:51:05-05:00 | changed formatting of wages earned | 9630e123f8748bb8260da27498e3600a3271e4c2 |
2018-11-23 14:14:38-05:00 | changed license to Apache 2.0' | b7791826f2df0212ce49b51b621dd7e7cc0d6f14 |
2019-02-25 10:19:10-05:00 | clock in T-1hr | d7add63b4d2e3e1ca1423296aaed25d9c28944da |
2019-02-25 12:49:51-05:00 | clock out T-5m | acfb8596317786e38177345aa2531098043a5c49 |
get_labor
通过不同的提交时间戳计算工作小时数,如果传入和传出的时钟长度不同,则会引发错误。
获取时间卡
importpandasaspdpd.set_option('display.width',400)
get_labor(work,end_date='2018-10-20 02:11:54-04:00')
pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 02:11:54-04:00
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
TimeIn | log in | TimeOut | log out | TimeDelta | |
---|---|---|---|---|---|
0 | 2018-10-19 23:57:48-04:00 | clock in | 2018-10-20 00:39:11-04:00 | clock out - work done for the day | 00:41:23 |
1 | 2018-10-20 01:06:08-04:00 | clock in - start adding requirements and examp... | 2018-10-20 01:47:01-04:00 | clock out | 00:40:53 |
2 | 2018-10-20 01:47:45-04:00 | clock in - pro bono | 2018-10-20 01:51:36-04:00 | clock out - pro bono | 00:03:51 |
3 | 2018-10-20 02:03:56-04:00 | clock in - finishing tutorial | 2018-10-20 02:11:54-04:00 | clock out - converted notebook for README | 00:07:58 |
处理错误的时钟输入/输出消息
如果您错误地在消息中输入“打卡”,则Hourly会将消息解释为合法的结束时间。这可能会在计算劳动力时产生错误。例如,此回购的历史记录中存在问题提交:
problematic_commit=work[work.hash=='d9ec537b36475b565df6b28d0cab6edc3a89f2da']problematic_commit
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
message | hash | |
---|---|---|
time | ||
2018-10-20 02:14:21-04:00 | had to clock out so notebook examples don't break | d9ec537b36475b565df6b28d0cab6edc3a89f2da |
当我们将其包含在劳动计算中时,会得到以下错误:
try:get_labor(work,end_date='2018-10-20 13:16:13-04:00')exceptValueErrorase:print(e)
pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00
In/Out logs do not match
我们可以通过设置errant_clocks
get_labor(work,end_date='2018-10-20 13:16:13-04:00',errant_clocks=['d9ec537b36475b565df6b28d0cab6edc3a89f2da'])
pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
TimeIn | log in | TimeOut | log out | TimeDelta | |
---|---|---|---|---|---|
0 | 2018-10-19 23:57:48-04:00 | clock in | 2018-10-20 00:39:11-04:00 | clock out - work done for the day | 00:41:23 |
1 | 2018-10-20 01:06:08-04:00 | clock in - start adding requirements and examp... | 2018-10-20 01:47:01-04:00 | clock out | 00:40:53 |
2 | 2018-10-20 01:47:45-04:00 | clock in - pro bono | 2018-10-20 01:51:36-04:00 | clock out - pro bono | 00:03:51 |
3 | 2018-10-20 02:03:56-04:00 | clock in - finishing tutorial | 2018-10-20 02:11:54-04:00 | clock out - converted notebook for README | 00:07:58 |
4 | 2018-10-20 11:53:00-04:00 | clock in - handling errant messages | 2018-10-20 13:16:13-04:00 | clock out - converting to pd.Timestamp | 01:23:13 |
过滤工作会话关键字
使用“忽略”关键字跳过不希望包含在发票中的任何工作。
labor=get_labor(work,ignore='pro bono',end_date='2018-10-20 13:16:13-04:00',errant_clocks=['d9ec537b36475b565df6b28d0cab6edc3a89f2da'])labor
pay period: 2018-10-19 23:57:48-04:00 -> 2018-10-20 13:16:13-04:00
ignoring pro bono
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
TimeIn | log in | TimeOut | log out | TimeDelta | |
---|---|---|---|---|---|
0 | 2018-10-19 23:57:48-04:00 | clock in | 2018-10-20 00:39:11-04:00 | clock out - work done for the day | 00:41:23 |
1 | 2018-10-20 01:06:08-04:00 | clock in - start adding requirements and examp... | 2018-10-20 01:47:01-04:00 | clock out | 00:40:53 |
3 | 2018-10-20 02:03:56-04:00 | clock in - finishing tutorial | 2018-10-20 02:11:54-04:00 | clock out - converted notebook for README | 00:07:58 |
4 | 2018-10-20 11:53:00-04:00 | clock in - handling errant messages | 2018-10-20 13:16:13-04:00 | clock out - converting to pd.Timestamp | 01:23:13 |
获得总收益
使用此函数可以找到总收入。货币只是用于打印的字符串,但将来我们可以添加单位转换。
get_earnings(labor,wage=30,currency='USD')
0 days 02:53:27, 2.89 hours worked
86.72 USD
86.72
时间调整
如果你忘记打卡或打卡,你可以调整你的时钟时间来修正你的时间表。默认情况下,当提交消息包含关键字“t-”时,Hourly会自动调整时间戳。将correct_times
设置为false可覆盖此行为。
work=get_work_commits('.',correct_times=False)# reports the actual time of the commitwork=work[work.message.str.contains('T-')]#filter by T-work
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
message | hash | |
---|---|---|
time | ||
2019-02-25 11:19:10-05:00 | clock in T-1hr | d7add63b4d2e3e1ca1423296aaed25d9c28944da |
2019-02-25 12:54:51-05:00 | clock out T-5m | acfb8596317786e38177345aa2531098043a5c49 |
work=get_work_commits('.')# reports actual work time, according to commit messagework=work[work.message.str.contains('T-')]#filter by T-work
<;样式范围>;
.dataframe tbody tr th:仅为{
垂直对齐:中间;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
<;/样式>;
message | hash | |
---|---|---|
time | ||
2019-02-25 10:19:10-05:00 | clock in T-1hr | d7add63b4d2e3e1ca1423296aaed25d9c28944da |
2019-02-25 12:49:51-05:00 | clock out T-5m | acfb8596317786e38177345aa2531098043a5c49 |
注意:目前只支持时间减法。
时间增量格式
Hourly使用Pandas的TimeDelta格式修改时间。这允许大量的灵活性。
pd.Timedelta('1hr45m')
Timedelta('0 days 01:45:00')