CIS 111 Control break report II

Objectives

  • Read data from a binary file
  • Convert a record of binary data into its constituent fields
  • Calculate the number of records in a binary file
  • Write a loop to process all the records in a binary file
  • Process control breaks correctly
  • Calculate sums for groupings of input data
  • Implement an algorithm
  • Properly format output data on a report

Program requirements

This assignment involves the creation of a flowchart and a level break report by translating the supplied algorithm. The data must be in correct sorted order for this algorithm to work. The supplied data file has already been put into the proper sorted order. Your program must read each of the records from the data file, convert the binary record into fields, and produce a control break report to a disk file named cb2rpt.txt. Your report should match the sample report exactly, including ALL formatting and spacing. Please note that since you are sending it to a disk file, you will not see the report on the screen when you run the program. You can view it later by opening it up in a text editor.

The data in the input file is in binary format, so you will not be able to read it with a text editor. Your program will read each binary record and convert into the correct data types to process the data and produce the report. The format of each record is as follows:

  • department: string (3 characters)
  • employee id: string (5 characters)
  • month: integer
  • day: integer
  • year: integer
  • hours: double (floating-point number)

The data file needed for this assignment is located at: cb2data.dat.

Sample Output

Daily hours worked by Department by Employee Dept EmpID Date Hours IT D4772 1/02/2011 8.25 IT D4772 1/03/2011 7.00 IT D4772 1/05/2011 9.25 IT D4772 1/06/2011 9.00 IT D4772 1/08/2011 7.25 Employee total 40.75 IT F9642 1/04/2011 8.25 IT F9642 1/06/2011 7.25 IT F9642 1/07/2011 5.25 IT F9642 1/08/2011 8.00 Employee total 28.75 IT V1001 1/03/2011 5.25 IT V1001 1/04/2011 8.50 IT V1001 1/05/2011 6.75 IT V1001 1/06/2011 6.75 IT V1001 1/07/2011 8.00 IT V1001 1/08/2011 6.00 Employee total 41.25 Department total 110.75 MGT A0010 1/02/2011 6.50 MGT A0010 1/03/2011 8.25 MGT A0010 1/04/2011 9.25 MGT A0010 1/05/2011 9.75 MGT A0010 1/06/2011 5.50 MGT A0010 1/07/2011 8.75 MGT A0010 1/08/2011 8.75 Employee total 56.75 MGT S0812 1/04/2011 5.25 MGT S0812 1/05/2011 7.75 MGT S0812 1/06/2011 7.25 MGT S0812 1/07/2011 6.00 MGT S0812 1/08/2011 9.50 Employee total 35.75 Department total 92.50 MKT H6554 1/02/2011 9.25 MKT H6554 1/03/2011 8.00 MKT H6554 1/04/2011 5.75 MKT H6554 1/05/2011 8.75 MKT H6554 1/06/2011 8.50 MKT H6554 1/08/2011 6.00 Employee total 46.25 Department total 46.25 MNT E5109 1/02/2011 8.75 MNT E5109 1/03/2011 5.50 MNT E5109 1/04/2011 6.00 MNT E5109 1/06/2011 5.00 MNT E5109 1/08/2011 6.50 Employee total 31.75 Department total 31.75 MSC E4100 1/03/2011 5.75 MSC E4100 1/04/2011 8.75 MSC E4100 1/05/2011 7.25 MSC E4100 1/07/2011 6.50 MSC E4100 1/08/2011 8.75 Employee total 37.00 Department total 37.00 PRD A0132 1/04/2011 9.00 PRD A0132 1/05/2011 8.00 PRD A0132 1/06/2011 8.75 PRD A0132 1/07/2011 9.00 PRD A0132 1/08/2011 5.00 Employee total 39.75 PRD E1231 1/02/2011 6.75 PRD E1231 1/03/2011 8.25 PRD E1231 1/04/2011 6.75 PRD E1231 1/06/2011 8.00 PRD E1231 1/07/2011 5.50 PRD E1231 1/08/2011 7.25 Employee total 42.50 PRD E1250 1/02/2011 9.75 PRD E1250 1/03/2011 7.75 PRD E1250 1/04/2011 7.75 PRD E1250 1/05/2011 7.50 Employee total 32.75 Department total 115.00 SLS L1776 1/02/2011 9.00 SLS L1776 1/03/2011 7.75 SLS L1776 1/04/2011 6.75 SLS L1776 1/06/2011 5.50 SLS L1776 1/08/2011 8.75 Employee total 37.75 SLS M5205 1/02/2011 7.00 SLS M5205 1/03/2011 5.00 SLS M5205 1/04/2011 7.75 SLS M5205 1/05/2011 6.00 SLS M5205 1/06/2011 7.75 SLS M5205 1/07/2011 5.25 SLS M5205 1/08/2011 8.25 Employee total 47.00 Department total 84.75 Total hours worked 518.00 70 records processed

Pseudocode

To make life even easier for you, here's the pseudocode for the program:

open input file for binary access open output (report) file print headings to report file totHours = empHours = deptHours = 0 prevID = prevDept = "$$$" let numrecs = the calculated number of records in the file for recno = 1 to numrecs read the next record from the input file parse the record just read into its constituent fields if record's dept is different than prevDept and recno > 1 // employee level break print employee's total hours to output file add empHours to deptHours empHours = 0 // department level break print department's total hours to output file add deptHours to totHours deptHours = 0 otherwise if record's employee id is different than prevID and recno > 1 // employee level break print employee's total hours to output file add empHours to deptHours empHours = 0 print formatted record detail to output file add record's hours to empHours prevID = record's employee id prevDept = record's department close input file // employee level break print employee's total hours to output file add empHours to deptHours empHours = 0 // department level break print department's total hours to output file add deptHours to totHours deptHours = 0 print grand totals to output file print footers to output file close output file end

Notes

  • The size of a record is the sum of the parts. In this case, eight bytes for the strings, four bytes for each of the three integers, and eight bytes for the double. That makes the total record size twenty eight bytes.
  • You can get the file size by importing the os module and using: fileSize = os.path.getsize(filename)
  • You can calculate the number of fixed-length records in a file by dividing the file size by the record length. It should divide with no remainder. If there is a remainder, the data file is corrupted.
  • Reading a binary record from a file is easy: record = file.read(sizeOfRecordInBytes)
  • You can convert the binary record into data fields by importing the struct module and using the struck.unpack(formatString, record) function.
  • The format string used in the unpack function specifies the byte order, type of field, and size of field. The byte order in this case should be specified with ">". Strings are specified using their length followed by an "s". Integers are specified using an "i". Double values are specified using a "d". So the format string for the records in this data file should be: ">3s5siiid".
  • The unpack function returns a tuple with an element for each field in the unpacked record.
  • You can convert a Python byte literal to a string using the decode function. For example, if element 0 in a tuple (named tpl) is a byte literal, you can convert it using: str = tpl[0].decode()

Rubric

  • 12 points for creating a correct flowchart
  • 2 points for comments at the start with program name, student name, assignment, date, course, program description
  • 2 points for correctly following coding conventions (indentation, naming rules, NO tabs, etc.)
  • 2 points for correctly calculating the total number of records in the binary file
  • 5 points for correctly reading each binary record in a loop
  • 6 points for correctly converting each binary record into the proper data fields
  • 5 points for handling level breaks correctly and having the correct totals
  • 5 points for matching the sample output format
  • 1 point for displaying the total number of records processed at the end