Python:用#字符分割文本文件并汇总总数

main()invoice.close()和位于其上方的print函数都会引发“无效语法”异常。

我对字典或函数一无所知(目前),所以这是我能想到的最好的方法。

这是我想要的结果:

Python:用#字符分割文本文件并汇总总数

以下是invoice.txt的内容:

#### CONTENTS OF invoice.txt ###
# hammer#9.95
# saw#20.15
# shovel#35.40

编辑*** 这是添加括号的例外 enter image description here

print('{0: <10}'.format('Item'),'{0: >17}'.format('Cost'),sep = '' )

def main():
    invoice = open("invoice.txt","r")

    count = 0
    total = 0

    hammer = invoice.readline()

    while invoice != "":
        saw = invoice.readline()
        shovel = invoice.readline()

        hammer = hammer.rstrip("\n")
        saw = saw.rstrip("\n")
        shovel = shovel.rstrip("\n")

        hammer = hammer.split("#")
        saw = saw.split("#")
        shovel = shovel.split("#")

        print('{0: <10}'.format(hammer[0]),'{0: >17}'.format('$' + hammer[1]),sep = '' )
        print('{0: <10}'.format(saw[0]),'{0: >17}'.format('$' + saw[1]),sep = '' )
        print('{0: <10}'.format(shovel[0]),'{0: >17}'.format('$' + shovel[1]),sep = '' )

        # total = total + float(hammer[1]) + float(saw[1]) + float(shovel[1])         # DOEsn"T WORK
        total = total + (int(float(hammer[1])) + int(float(saw[1])) + int(float(shovel[1]))

        # total = total + (int(hammer[1])) + (int(saw[1])) + (int(shovel[1]))         # DOEsn"T WORK
        print("{0: <10}".format("Total cost") + "{0: >17}".format("{0:.2f}".format(float(total))))

    invoice.close()
main()

leikai945 回答:Python:用#字符分割文本文件并汇总总数

假设内容实际上只是

hammer#9.95
saw#20.15
shovel#35.40

这只是一个DSV,使用#作为分隔符。幸运的是,大多数CSV程序都支持多个定界符,包括python的定界符。

import csv
from io import StringIO 


def print_report(items,fields):
    print("\t".join(fields))
    total_cost = sum(float(item["Cost"]) for item in items) 
    for item in items:
        print(f"{item['Item']}\t${float(item['Cost']):.2f}")
    print()
    print(f"Total cost\t${total_cost:.2f}")
    print(f"Number of tools\t{len(items)}")

fields = ["Item","Cost"]
# This StringIO is basically like opening a file
s = StringIO(u"hammer#9.95\nsaw#20.15\nshovel#35.40")
items = list(csv.DictReader(s,delimiter="#",fieldnames=fields))
print_report(items,fields)

Item    Cost
hammer  $9.95
saw $20.15
shovel  $35.40

Total cost  $65.50
Number of tools 3
,

这里的许多格式代码都是多余的,并且对文本文件中的名称进行硬编码是不可扩展的。如果需要引入新项目,则必须更改所有代码。我们应该通过编写一个辅助函数来处理打印,从而保持DRY的状态。 format可以接受多个参数,从而简化了事情。

其他所有事情都与读取文件有关(使用上下文管理器with,因此您不必担心记住调用close),匹配有效行,拆分,剥离和转换数据。一旦所有内容都在列表中,我们就可以在该列表上调用sumlen函数以生成所需的总计。

我已经硬编码了列大小-那些确实应该是参数,我们应该遍历数据以预先计算列名。但这可能太过分了。

如果您的数据实际上是CSV,但其余代码几乎相同,请使用CSV库。

import re

def fmt(x,y):
    if isinstance(y,float):
        y = "$" + "{:1,.2f}".format(y).rjust(5)

    return '{0:<18}{1:>10}'.format(x,y)

if __name__ == "__main__":
    items = []

    with open("invoice.txt","r") as f:
        for line in f:
            if re.search(r"#\d+\.\d+$",line):
                items.append([x.strip() for x in line.split("#") if x])

    print(fmt("Name","Cost"))

    for name,price in items:
        print(fmt(name,float(price)))

    print()
    print(fmt("Total cost",sum([float(x[1]) for x in items])))
    print(fmt("Number of tools",len(items)))

输出:

Name                    Cost
hammer                $ 9.95
saw                   $20.15
shovel                $35.40
Total cost            $65.50
Number of tools            3
,

语法错误

让我们退后一步,看看为什么您的代码无法正常工作。 这是我运行您的代码时收到的错误消息:

  File "test_2.py",line 31
    print("{0: <10}".format("Total cost") + "{0: >17}".format("{0:.2f}".format(float(total))))
        ^
SyntaxError: invalid syntax

在Python中读取错误消息时,一开始会有很多信息可能会让人不知所措,但是一旦您学习了如何提取信息,它们将非常有帮助!让我们分解错误消息:

  • 错误发生在test_2.py的第31行。在这种情况下,test_2是我称为文件的文件,您的文件可能有所不同。
  • 错误的类型是语法错误,这意味着Python无法正确解析代码行。
  • 请注意print statement下的箭头:这准确指示了解析过程中引发错误的符号。

弹出的一个非常常见的语法错误是括号不匹配。使得该错误更加棘手的是,解析器将告诉您发现括号匹配问题的点,但是该问题可能位于完全不同的行上。这正是这里发生的情况,因此,我对syndax错误的一般规则是检查错误告诉您检查的行以及之前和之后的几行。 让我们仔细看看您指出的两行无效:

total = total + (int(float(hammer[1])) + int(float(saw[1])) + int(float(shovel[1]))

print("{0:<10}".format("Total cost") + "{0:>17}".format("{:.2f}".format(float(total))))

在第一行中,打开一个仿体(,然后在int()float()和{{1}上分别调用hammersaw },但您永远不要放下右括号!因此错误似乎早于Python所说的,但是从解析器的角度来看,目前实际上没有问题。直到解析器到达第31行,我们才出现问题。解析器原本希望括号是闭合的,但是它却得到了shovel函数,并在第31行的print函数处而不是在前一行缺少括号的地方引发了错误。>

这些类型的东西需要时间来适应,但是随着时间的推移,您将学习技巧和窍门。

更好地使用变量

在Python程序中,您不应假定文本文件的内容。目前,您假设将只有3个项目,并且变量名似乎反映了您假设这些项目将是什么。如果文本文件包含数千个项目,会发生什么?为文本文件中的每个项目都创建一个新变量是不可行的。您应使用print之类的通用名称,而不要使用toolhammersaw,并在循环的单独迭代中而不是全部使用文本文件中的每个项。一次。

示例解决方案

这是为您提供的示例解决方案。如您所说,使用字典会很好,因此下面的解决方案实现了一个返回项字典的函数,其中键是项名称,值是项成本。然后使用shovel函数返回发票的格式化字符串,并打印出发票。

get_invoice
本文链接:https://www.f2er.com/3042992.html

大家都在问