pythonlisttext-filesexport-to-csvdot-matrix

Write a Python script that prints tickets in columns


I’m struggling to write a Python script to process a file and produce an output text file containing the tickets in a format that is ready for printing via a dot matrix printer. For reference I have also attached an example of what the resultant text file should look like.

ConcertTickets.txt and ConcertTickets_result.txt

My major problem is architecting an approach to this problem. I can’t figure out how to print column by column. I was able to read the file, print row by row, do the validation and write the file with a new name. I’m not sure how to do the layout_name, columns, column_width, column_spacing, left_margin, row spacing and line_item, the best I could do was ljust() for the left margin between the tickets.

I don’t expect someone to do the work for me, but would greatly appreciate tips on architectural approaches with and without third party packages.

The input concert ticket file consists of a header containing formatting information and a body containing the actual tickets.

The header lines are as follows:

The script also needs to do some basic file validation by checking that the number of actual tickets in the body of the file match the ticket summary values in the header of the file. If file validation fails the program must exit with an appropriate error message.

The resultant output file name must be the same as the input file name, but with the word "_result" appended to it just before the file extension. E.g. if the input file name is ConcertTickets.txt then the output file name must be ConcertTickets_result.txt

I also need to develop a set of test cases for the script.

This is my code thus far

data = []
data_description = []
data_pin = []
data_serial_number = []
data_expiry_date = []
tickets_in_body = 0

# read file from line 19 and create two-dimensional array 

result_f = open('ConcertTickets.txt')

for each_line in result_f.readlines()[18:]:
    (description, pin, serial_number, expiry_date) = each_line.split(',')
    data_description.append(description)
    data_pin.append(pin)
    data_serial_number.append(serial_number)
    data_expiry_date.append(expiry_date.replace("\r\n",""))
    tickets_in_body += 1

data = [data_description, data_pin, data_serial_number, data_expiry_date]

# ticket validation and writing to file

result_golden_summary = open('ConcertTickets.txt')
golden_summary = result_golden_summary.readlines()
(golden_description, golden_summary_amount, golden_summary_value) = (golden_summary[15 - 1]).split(',')

if int(golden_summary_amount) != tickets_in_body:
    print('The ticket summary in the header does not match the amount of tickets in body')
else:
    (filename, extension) = (result_f.name).split('.')
    result_f = open(filename + "_result.txt", 'w')
    for row in data:
        result_f.write("".join(str(item).ljust(25) for item in row))

result_f.close()

Solution

  • here's some code for you:

    import math
    
    result_f = open('ConcertTickets.txt')
    
    all_lines_arr = []
    for each_line in result_f.readlines()[18:]:
        (description, pin, serial_number, expiry_date) = each_line.split(',')
    
        line_dict = {}
    
        line_dict["description"] = description
        line_dict["pin"] = pin
        line_dict["serial_number"] = serial_number
        line_dict["expiry_date"] = expiry_date.strip()
    
        all_lines_arr.append(line_dict)
    
    per_row = 5
    line_space = 30
    rows = math.ceil(len(all_lines_arr)/per_row)
    for i in range(0, rows):
        row_val = (i*per_row)+per_row
        if (row_val > len(all_lines_arr)):
            row_val = row_val - (row_val-len(all_lines_arr))
    
        for j in range((i*per_row), row_val):
            print(all_lines_arr[j]["pin"] + (line_space-(len(all_lines_arr[j]["pin"]))%line_space)*" ", end="")
        print("\n"*2)
        for j in range((i*per_row), row_val):
            print(all_lines_arr[j]["description"] + (line_space-(len(all_lines_arr[j]["description"]))%line_space)*" ", end="")
        print()
        for j in range((i*per_row), row_val):
            print(all_lines_arr[j]["serial_number"] + (line_space-(len(all_lines_arr[j]["serial_number"]))%line_space)*" ", end="")
        print()
        for j in range((i*per_row), row_val):
            print(all_lines_arr[j]["expiry_date"] + (line_space-(len(all_lines_arr[j]["expiry_date"]))%line_space)*" ", end="")
        print("\n"*5)
    

    First we read the lines, and put them into an array of dictionaries i.e. each array element is a dictionary, which has an addressable value e.g. description

    Next, we use per_row to decide how many tickets to print per row (you can change this).

    Then the code will print the dictionary values for each element in the array.

    The key to the formatting is that it uses modulus % to print the correct number of spaces. I used 30 as the separator.

    I stripped out a lot of your code in order to just do the print formatting for you. It will be up to you to modify this to print to file or do anything else you need it to.

    It is a bit too hardcoded for my liking, but without knowing more about exactly what you need, it works for your simple case.

    Hope this helps!