patternpythonMinor
Track hours worked total or per month
Viewed 0 times
totaltrackperworkedhoursmonth
Problem
I track the hours that I have worked on something in an Excel sheet (actually Google Spreadsheet, but semantics). This is tracked in the following format:
Date | Start (time) | End (time) | Description
I can download this as a CSV and my program will run through it and tell me how many hours I've worked in total and per month. It can also calculate the tax that will go over it. (Keep in mind, these are Dutch taxes).
CSV example:
hours.py:
`#!/usr/bin/env python
# -- encoding: utf-8 --
"""
This script reads the worked hours from CSV file generated from
Google docs / Excel and generates statistics from it.
The CSV file should be in format:
Date,Start,End,Description
"""
import argparse
import csv
import os
from models import Stats
def hours_minutes(td):
"""Converts timedelta object into hours and minutes"""
return (td.seconds // 3600) + (td.days * 24), (td.seconds // 60) % 60
def calculate_salary(rate, td, tax=0):
"""
Calculates the salary based on the amount of time worked.
Tax is deduced from the total amount, not the hourly rate.
:rate: The hourly rate
:td: timedelta with the amount of time worked.
"""
hours, minutes = hours_minutes(td)
total = hours * rate
if minutes: # to prevent ZeroDivisionError
total += (minutes / 60.0) * rate
if tax:
total = total - (total / 100 * tax)
return total
def print_salary(args, total_time, prepend=''):
"""
Prints the total salary and the total salary with the taxes taken off.
:args: The command line args from argparse
:total_time: Timedelta that will be used to print the number of hours
:prepend: String to prepend to the print out. For example '\t' for indent.
"""
print(prepend + 'Total salary: €{salary:.2f}'.format(
salary=calculate_salary(args['rate'], total_time)))
print(prepend + 'Total salary taxed: €{salary:.2f} tax: {tax:.2f}%'.format
Date | Start (time) | End (time) | Description
I can download this as a CSV and my program will run through it and tell me how many hours I've worked in total and per month. It can also calculate the tax that will go over it. (Keep in mind, these are Dutch taxes).
CSV example:
Date,Start,End,Description
2016-11-11,16:00,16:45,Demo
hours.py:
`#!/usr/bin/env python
# -- encoding: utf-8 --
"""
This script reads the worked hours from CSV file generated from
Google docs / Excel and generates statistics from it.
The CSV file should be in format:
Date,Start,End,Description
"""
import argparse
import csv
import os
from models import Stats
def hours_minutes(td):
"""Converts timedelta object into hours and minutes"""
return (td.seconds // 3600) + (td.days * 24), (td.seconds // 60) % 60
def calculate_salary(rate, td, tax=0):
"""
Calculates the salary based on the amount of time worked.
Tax is deduced from the total amount, not the hourly rate.
:rate: The hourly rate
:td: timedelta with the amount of time worked.
"""
hours, minutes = hours_minutes(td)
total = hours * rate
if minutes: # to prevent ZeroDivisionError
total += (minutes / 60.0) * rate
if tax:
total = total - (total / 100 * tax)
return total
def print_salary(args, total_time, prepend=''):
"""
Prints the total salary and the total salary with the taxes taken off.
:args: The command line args from argparse
:total_time: Timedelta that will be used to print the number of hours
:prepend: String to prepend to the print out. For example '\t' for indent.
"""
print(prepend + 'Total salary: €{salary:.2f}'.format(
salary=calculate_salary(args['rate'], total_time)))
print(prepend + 'Total salary taxed: €{salary:.2f} tax: {tax:.2f}%'.format
Solution
Division by zero?
So what if
(Also, if you think that
Reducing over addition
You write
if minutes: # to prevent ZeroDivisionError
total += (minutes / 60.0) * rate
if tax:
total = total - (total / 100 * tax)So what if
minutes = 0? Then total = (0 / 60.0) * rate = 0 It doesn't cause a division error. Same goes for tax = 0.(Also, if you think that
minutes could become 1/0 or some other sort of indeterminate form, the program will fail well before you get to that if statement.)Reducing over addition
You write
reduce(operator.add ... ) a few times. There is common name for this operation, it's called sum, and it is included by default, so you should be able to get rid of import operator all together.Code Snippets
if minutes: # to prevent ZeroDivisionError
total += (minutes / 60.0) * rate
if tax:
total = total - (total / 100 * tax)Context
StackExchange Code Review Q#151475, answer score: 2
Revisions (0)
No revisions yet.