简介
在这个实验中,你将学习回顾 Python 中的基本文件输入和输出操作。你将创建一个 Python 程序,从包含股票投资组合信息的文件中读取数据,并计算该投资组合的总成本。
本实验的目标包括学习如何在 Python 中打开和读取文件、逐行处理文件中的数据、对数据进行计算以及输出结果。你将创建的文件是 pcost.py。
理解问题
在这一步中,我们首先要明确需要解决的问题是什么,然后查看我们要处理的数据。这是任何编程任务的重要第一步,因为它能帮助我们确切地知道目标是什么,以及我们可以利用哪些资源。
在你的项目目录中,有一个名为 portfolio.dat 的文件。这个文件存储了股票投资组合的信息。投资组合就像是投资者持有的不同股票的集合。该文件中的每一行代表一次股票购买。每行的格式如下:
[股票代码] [股数] [每股价格]
股票代码是代表某家公司股票的简短代码。股数表示购买了该股票的多少单位,每股价格则是该股票一个单位的成本。
让我们来看一个例子。考虑文件的第一行:
AA 100 32.20
这一行表明购买了 100 股代码为“AA”的股票。每股的成本是 32.20 美元。
如果你想查看 portfolio.dat 文件的内容,可以在终端中运行以下命令。cat 命令是终端中一个有用的工具,它可以让你查看文件的内容。
cat ~/project/portfolio.dat
现在,你的任务是创建一个名为 pcost.py 的 Python 程序。这个程序将执行三个主要任务:
- 首先,它需要打开并读取
portfolio.dat文件。在 Python 中打开文件可以让我们的程序访问存储在其中的数据。 - 然后,它必须计算投资组合中所有股票购买的总成本。为此,对于文件中的每一行,我们需要将股数乘以每股价格。得到每一行的这些值后,将它们全部相加。这样我们就得到了投资组合中所有股票的总花费。
- 最后,程序应该输出总成本。这样,我们就可以看到计算的结果。
让我们从创建 pcost.py 文件开始。你可以使用编辑器打开并编辑这个文件。在设置步骤中已经为你创建好了这个文件。这个文件将是你编写 Python 代码来解决我们刚刚讨论的问题的地方。
打开并读取文件
在这一步中,你将学习如何在 Python 中打开并读取文件。文件输入/输出(I/O)是编程中的一个基本概念。它允许你的程序与外部文件(如文本文件、CSV 文件等)进行交互。在 Python 中,处理文件最常用的方法之一是使用 open() 函数。
open() 函数用于在 Python 中打开文件。它接受两个重要参数。第一个参数是你要打开的文件的名称。第二个参数是你打开文件的模式。当你要读取文件时,使用模式 'r'。这告诉 Python 你只想读取文件的内容,而不做任何修改。
现在,让我们在 pcost.py 文件中添加一些代码来打开并读取 portfolio.dat 文件。在代码编辑器中打开 pcost.py 文件,并添加以下代码:
## pcost.py
## Calculate the total cost of a portfolio of stocks
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
"""
total_cost = 0.0
## Open the file
with open(filename, 'r') as file:
## Read all lines in the file
for line in file:
print(line) ## Just for debugging, to see what we're reading
## Return the total cost
return total_cost
## Call the function with the portfolio file
total_cost = portfolio_cost('portfolio.dat')
print(f'Total cost: ${total_cost}')
让我们来详细分析这段代码的功能:
- 首先,我们定义了一个名为
portfolio_cost()的函数。这个函数接受一个文件名作为输入参数。该函数的目的是根据文件中的数据计算股票投资组合的总成本。 - 在函数内部,我们使用
open()函数以只读模式打开指定的文件。这里使用with语句确保在读取完文件后正确关闭文件。这是避免资源泄漏的良好实践。 - 然后,我们使用
for循环逐行读取文件。对于文件中的每一行,我们将其打印出来。这只是为了调试,以便我们可以查看从文件中读取的数据。 - 读取完文件后,函数返回总成本。目前,总成本被设置为 0.0,因为我们还没有实现实际的计算。
- 在函数外部,我们使用文件名
'portfolio.dat'调用portfolio_cost()函数。这意味着我们要求该函数根据portfolio.dat文件中的数据计算总成本。 - 最后,我们使用 f-string 打印总成本。
现在,让我们运行这段代码,看看它的效果。你可以在终端中使用以下命令运行 Python 文件:
python3 ~/project/pcost.py
当你运行此命令时,你应该会在终端上看到 portfolio.dat 文件的每一行被打印出来,后面跟着总成本,目前总成本被设置为 0.0。这个输出可以帮助你验证文件是否被正确读取。
处理数据
既然你已经学会了如何读取文件,下一步就是处理文件的每一行,以计算每笔股票交易的成本。这是在 Python 中处理数据的重要环节,因为它能让你从文件中提取有意义的信息。
文件中的每一行都遵循特定的格式:[股票代码] [股数] [每股价格]。要计算每笔股票交易的成本,你需要从每一行中提取股数和每股价格。然后,将这两个值相乘,得到该笔股票交易的成本。最后,将这笔成本累加到总成本中,以得出投资组合的总费用。
让我们修改 pcost.py 文件中的 portfolio_cost() 函数来实现这一点。以下是修改后的代码:
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
"""
total_cost = 0.0
## Open the file
with open(filename, 'r') as file:
## Read all lines in the file
for line in file:
## Strip any leading/trailing whitespace
line = line.strip()
## Skip empty lines
if not line:
continue
## Split the line into fields
fields = line.split()
## Extract the relevant data
## fields[0] is the stock symbol (which we don't need for the calculation)
shares = int(fields[1]) ## Number of shares (second field)
price = float(fields[2]) ## Price per share (third field)
## Calculate the cost of this stock purchase
cost = shares * price
## Add to the total cost
total_cost += cost
## Print some debug information
print(f'{fields[0]}: {shares} shares at ${price:.2f} = ${cost:.2f}')
## Return the total cost
return total_cost
让我们逐步分析这个修改后的函数的功能:
- 去除空白字符:使用
strip()方法去除每行开头和结尾的空白字符。这样可以确保在将行拆分为字段时不会意外包含多余的空格。 - 跳过空行:如果某行是空的(即只包含空白字符),使用
continue语句跳过该行。这有助于避免在尝试拆分空行时出错。 - 将行拆分为字段:使用
split()方法根据空白字符将每行拆分为一个字段列表。这样就可以分别访问行中的每个部分。 - 提取相关数据:从字段列表中提取股数和每股价格。股数是第二个字段,每股价格是第三个字段。将这些值转换为适当的数据类型(股数为
int类型,价格为float类型),以便进行算术运算。 - 计算成本:将股数乘以每股价格,计算出该笔股票交易的成本。
- 累加到总成本:将该笔股票交易的成本累加到总成本中。
- 打印调试信息:打印每笔股票交易的相关信息,帮助你了解程序的运行情况。这些信息包括股票代码、股数、每股价格和交易总成本。
现在,让我们运行代码,看看是否能正常工作。打开终端并运行以下命令:
python3 ~/project/pcost.py
运行命令后,你应该会看到每笔股票交易的详细信息,后面跟着投资组合的总成本。这个输出将帮助你验证函数是否正常工作,以及你是否准确计算了总成本。
完成程序
现在,你要清理代码并创建 pcost.py 程序的最终版本。清理代码意味着移除任何不必要的部分,并确保输出结果美观。这是编程中的重要步骤,因为它能让你的代码更专业、更易理解。
你将从移除调试打印语句开始。这些语句在开发过程中用于检查变量的值和程序的流程,但在最终版本中并不需要。然后,你要确保最终输出的格式良好。
以下是 pcost.py 代码的最终版本:
## pcost.py
## Calculate the total cost of a portfolio of stocks
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
"""
total_cost = 0.0
try:
## Open the file
with open(filename, 'r') as file:
## Read all lines in the file
for line in file:
## Strip any leading/trailing whitespace
line = line.strip()
## Skip empty lines
if not line:
continue
## Split the line into fields
fields = line.split()
## Extract the relevant data
## fields[0] is the stock symbol (which we don't need for the calculation)
shares = int(fields[1]) ## Number of shares (second field)
price = float(fields[2]) ## Price per share (third field)
## Calculate the cost of this stock purchase and add to the total
total_cost += shares * price
except FileNotFoundError:
print(f"Error: Could not find file '{filename}'")
return 0.0
except Exception as e:
print(f"Error processing file: {e}")
return 0.0
## Return the total cost
return total_cost
## Main block to run when the script is executed directly
if __name__ == '__main__':
## Call the function with the portfolio file
total_cost = portfolio_cost('portfolio.dat')
print(f'Total cost: ${total_cost:.2f}')
这个最终版本的代码有几处改进:
- 错误处理:添加了代码来捕获两种类型的错误。当指定的文件不存在时,会引发
FileNotFoundError。如果发生这种情况,程序将打印错误消息并返回 0.0。Exception块捕获在处理文件时可能发生的任何其他错误。这使程序更健壮,减少了意外崩溃的可能性。 - 格式规范:使用 f-string 中的
:.2f格式说明符将总成本格式化为保留两位小数。这使输出看起来更专业、更易读。 __name__ == '__main__'检查:这是常见的 Python 惯用法。它确保if块内的代码仅在脚本直接执行时运行。如果脚本作为模块导入到另一个脚本中,这段代码将不会运行。这让你能更好地控制脚本的行为。
现在,让我们运行最终代码。打开终端并输入以下命令:
python3 ~/project/pcost.py
运行此命令时,程序将读取 portfolio.dat 文件,计算投资组合的总成本,并打印结果。你应该会看到投资组合的总成本,应为 $44671.15。
恭喜!你已成功创建了一个 Python 程序,它能从文件中读取数据、处理数据并计算结果。这是一项了不起的成就,表明你正在成为一名熟练的 Python 程序员。
总结
在这个实验中,你学习了如何在 Python 中执行基本的文件输入/输出(I/O)操作。你可以使用 open() 函数和上下文管理器来打开和读取文件,逐行处理数据,解析文本数据,进行计算,处理错误,以及使用函数和主程序块来构建一个完整的 Python 程序。
这些技能是许多 Python 程序的基础,并且在各种应用中都很有用,例如数据分析和配置管理。你可以通过添加命令行参数、处理不同的文件格式、改进错误检查以及生成更详细的报告来进一步完善这个程序。