1
\$\begingroup\$

I wrote a simple Python script that will calculate income for a given month and hourly wage by parsing the contents of a log file. The instructions for how to use it is in my GitHub account here. The script is used in the command line with the following command

python calculate_hours.py MY_LOG.txt MONTH YEAR HOURLY_WAGE
  • MY_LOG.txt is the text file containing the date and the number of hours worked on that day
  • MONTH and YEAR are the full (not abbreviated) month and year for which you'd like the income calculated (e.g. December 2015)
  • HOURLY_WAGE is, well, your hourly wage (e.g. 25)

The log file must be formatted in a specific way. An entry in the log should look like the following

**Date**: 21 December 2015
**Time**: 5pm - 7pm, 12-1am
**Hours**: 2, 1

**Notes**:
+ Debugged script written yesterday
+ Checked data 

The script depends on the information after **Date** and **Hours** to calculate income.

It's very simple and I was wondering if there was a way to improve it. The script looks for patterns in the log file to get the date and the hours worked.

import re
import argparse

def wage_calculator(log_txt_file, month, year, wage):

    date_pattern = "\*\*Date\*\*"  # pattern identifying the date in the file
    hours_full = []

    with log_txt_file as f:

        for line in log_txt_file:

            if re.search(r"{0}".format(date_pattern), line):  # go to the relevant line

                if re.search(month, line) and re.search(str(year), line):  # within line, go to desired month/year

                    # skips two lines to the line containing the number of hours worked
                    f.next()
                    hours_line = f.next()

                    hours_list_str = re.findall(r'[-+]?\d*\.*\d+', hours_line)  # put hours in a list
                    hours_list = [float(x) for x in hours_list_str]

                    hours_full += hours_list

                    sum_hours_date = sum(hours_list)

                    print line.rstrip()
                    print "Hours logged: " + str(hours_list)
                    print "Total hours for the day " + str(sum_hours_date) + "\n"

    hours_total = sum(hours_full)

    print "Total hours worked in {0} {1} is {2}".format(month, year,
                                                        hours_total)
    print "At ${0}/hr, your total wage for {1} {2} is ${3}".format(wage, month
                                                                   , year, hours_total * wage)


def main():

    parser = argparse.ArgumentParser()

    parser.add_argument("file",
                        help="Text file containing hours logged (e.g. ra_hours.txt)",
                        type=argparse.FileType('r')
                        )
    parser.add_argument("month",
                        help="The month for which we want the income",
                        type=str)
    parser.add_argument("year",
                        help="Enter year",
                        type=int)
    parser.add_argument("wage",
                        help="Enter hourly wage",
                        type=float)

    args = parser.parse_args()

    wage_calculator(args.file, args.month, args.year, args.wage)

if __name__ == '__main__':
    main()
\$\endgroup\$
  • \$\begingroup\$ Please include (at least some) instructions on how to use the code in your question. A very important part of the StackExchange idea is that questions are (predominantly) self-contained. \$\endgroup\$ – Tersosauros Mar 7 '16 at 4:42
1
\$\begingroup\$

I think regex is a bit much for this scale of project. I decided to try rewriting your function without using regex, and I think the result is much cleaner and more Pythonic.

In addition, I replaced your hours_full list of lists with a single number that tracks the total. This greatly simplifies the code.

However, the general structure is essentially the same.

def wage_calculator(log_txt_file, month, year, wage):
    date_pattern = "**Date**: "  # pattern identifying the date in the file
    hours_pattern = "**Hours**: " # pattern identifying the hours in the file
    hours_total = 0.0

    with log_txt_file as f:
        for line in log_txt_file:
            if line.startswith(date_pattern):
                if month in line and str(year) in line:
                    f.next() # skip a line
                    # skip the start of the line to just get a list of hours
                    hours_line = f.next()[len(hours_pattern):]
                    hours = sum(map(float, hours_line.split(', ')))

                    hours_total += hours

                    print line.rstrip()
                    print "Hours logged: " + hours_line
                    print "Total hours for the day " + str(hours) + "\n"

    print "Total hours worked in {0} {1} is {2}".format(month, year,
                                                        hours_total)
    print "At ${0}/hr, your total wage for {1} {2} is ${3}".format(wage, month
                                                                   , year, hours_total * wage)

Beyond this, I would look into more error handling and data cleanup. For example, verify that the **Hours** line matches the **Time** line.

Also a .txt doesn't seem suitable for this data, maybe use a .csv?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.