1

我正在努力编写一个 Python 脚本来处理一个文件并生成一个输出文本文件,其中包含可以通过点阵打印机打印的格式的票证。作为参考,我还附上了一个结果文本文件应该是什么样子的示例。

ConcertTickets.txtConcertTickets_result.txt

我的主要问题是构建解决此问题的方法。我不知道如何逐列打印。我能够读取文件,逐行打印,进行验证并用新名称写入文件。我不确定如何做 layout_name、columns、column_width、column_spacing、left_margin、行间距和 line_item,我能做的最好的就是 ljust() 用于票之间的左边距。

我不希望有人为我做这项工作,但非常感谢有关有和没有第三方包的架构方法的提示。

输入音乐会门票文件由包含格式信息的标题和包含实际门票的正文组成。

标题行如下:

  • download_datetime - 下载文件的日期和时间
  • order_datetime - 下订单的日期和时间
  • layout_name - 用于格式化工单的布局名称
  • columns - 每页宽度的工单列数
  • column_width - 每个工单列的宽度
  • column_spacing - 工单列之间的空格数
  • left_margin - 第一张票列左侧的前导空格
  • row_spacing - 票之间的水平线数
  • line_item - 行项目表示工单元素必须如何出现在工单中,例如顶部的 PIN,后跟两个空行,然后是描述、序列号和到期日期。行项目的有效值为:pin、description、serial_number、expiry_date 和 empty(空格)
  • ticket_summary - 每个票证摘要包含票证描述,后跟文件中该类型票证的数量和票证的总面值,例如“黄金 10.00,10,100.00”表示有 10 张价值 100.00 美元的黄金票文件
  • ticket_fields - 工单字段指示出现在随后的工单数据中的字段及其顺序。这是标题的最后一行,此行之后的所有数据都应解释为正文数据,即 CSV 类型格式的实际票证

该脚本还需要通过检查文件正文中的实际票证数量是否与文件头中的票证摘要值匹配来执行一些基本的文件验证。如果文件验证失败,程序必须退出并显示相应的错误消息。

结果输出文件名必须与输入文件名相同,但在文件扩展名之前附加单词“_result”。例如,如果输入文件名是 ConcertTickets.txt,那么输出文件名必须是 ConcertTickets_result.txt

我还需要为脚本开发一组测试用例。

到目前为止,这是我的代码

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()
4

2 回答 2

0

这是打开(和关闭)文件的推荐方式:

# open file as read ('r')
with open('ConcertTickets.txt', 'r') as file:
    for line in file.readlines()[18:]:
        # your logic 

# open result file as write ('w'), '+' creates the file if not exist
with open('ConcertTickets_result.txt', 'w+' as file:
    # your logic 
于 2020-06-04T15:22:56.080 回答
0

这是给你的一些代码:

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)

首先我们读取这些行,并将它们放入一个字典数组中,即每个数组元素都是一个字典,它有一个可寻址的值,例如description

接下来,我们per_row用来决定每行打印多少张票(您可以更改此设置)。

然后代码将打印数组中每个元素的字典值。

格式化的关键是它使用模数%来打印正确数量的空格。我使用 30 作为分隔符。

我删除了你的很多代码,以便为你做打印格式。您可以自行修改它以打印到文件或执行您需要的任何其他操作。

它对我来说有点太硬编码了,但是在不知道你到底需要什么的情况下,它适用于你的简单案例。

希望这可以帮助!

于 2020-06-04T17:06:23.593 回答