我编制了一个程序,计算出在给定的几年内,由于通货膨胀,货币价值下降了多少。这需要一个本金,一个开始和结束日期,并且在通货膨胀率的帮助下,它计算货币在本年度的价值。(化合物)
CSV文件中的数据来自这里。
这是密码-
import pandas
startDate = input("Enter the starting year ")
endDate = input("Enter the ending year ")
principal_amt = float(input("Enter the amount "))
startDate = startDate + "-12-" + "31"
endDate = endDate + "-12-" + "31"
final_amt = 0
print(startDate, endDate)
df = pandas.read_csv("india-cpi.csv")
df = df.set_index("date")
inflation_list = list(df.loc[startDate:endDate, " inflation-rate"])
print(inflation_list)
list_for_p = []
for item in inflation_list:
principal_amt += principal_amt*(item/100)
list_for_p.append(principal_amt)
print(list_for_p)
final_amt += principal_amt
print(final_amt)这就是输出的样子:
进入2016年年初
进入2018年年底
输入金额100
2016-12-31 2018-12-31
4.941,2.4909,4.8607
104.941,107.554975369,112.782900056761
112.782900056761
我想问一下我的计算是否正确,如果你有其他的建议,请给我。会有帮助的。谢谢!
发布于 2020-04-23 13:05:06
代码本身是足够清楚的,间距和变量命名是可以的。你把camelCase和snake_case混合在一起。坚持一个。PEP-8建议snake_case用于函数和变量名,PascalCase用于类。
只有principal_amt的缩写是相当徒劳的。只需使用全名,它要花费3个字符。
你最好把你的程序按功能分开:
这样,您的程序就更容易理解、测试和重用。
我关于在哪里拆分程序的经验法则是数据从一个部分交换到另一个部分的位置。
现在,您已经在逻辑块中分隔了程序,您可以开始测试各个部分。
创建一个小函数,将文件名作为参数传入,并每年将索引取回来。在这里,你可以进一步使用熊猫。首先,您可以将该年设置为pandas.Period,因此可以立即对该年进行索引。那么你已经可以进行除法了。由于熊猫有一个很好的cumprod函数,所以您可以在每个索引中添加1。
def get_inflation_rate(
filename: typing.Union[Path, str, typing.IO]
) -> pd.Series:
"""Read the inflation data from `filename`"""
inflation_rate = (
pd.read_csv(
data_file,
skiprows=16,
parse_dates=["date"],
usecols=[0, 1],
index_col=0,
)
.div(100)
.add(1)
.rename(columns={" Inflation Rate (%)": "inflation_rate"})
)["inflation_rate"]
inflation_rate.index = inflation_rate.index.to_period()
return inflation_rate这将返回一个以年份为指数,以通货膨胀率为值的系列。
date
1960 1.017799
1961 1.016952
1962 1.036322
1963 1.029462
...
2014 1.063532
2015 1.058724
2016 1.049410
2017 1.024909
2018 1.048607
Freq: A-DEC, Name: inflation_rate, dtype: float64我包括了一个docstring和输入信息,这样这个函数的用户和他的IDE就可以知道期望什么了。
如果您的用户返回一些废话,您的程序将没有什么用处。最好尽可能清楚地警告用户。您可以定义如下函数:
def get_input(
*, message, possible_values: typing.Optional[typing.Collection[str]] = None
) -> str:
while True:
value = input(message)
if possible_values is None or value in possible_values:
return value
print("Not one of the possibilities")如果需要,也可以将其转换为浮点数,更一般的方法如下所示:
T = typing.TypeVar("T")
def get_input(
*,
message: str,
possible_values: typing.Optional[typing.Collection[T]] = None,
converter: typing.Optional[typing.Callable[[str], T]] = None,
) -> typing.Union[T, str]:
"""Get and convert the user input.
Tries to call `converter` on the input value.
If this raises a `ValueError`, asks again.
If `possible_values` is defined, checks whether the returned value is in
this collection. If it is not, asks again.
Args:
message (str): The message to present to the user.
possible_values (typing.Collection[T], optional):
A selection which must contain the user input. Defaults to None.
converter (typing.Callable[[str], T], optional):
A function to try to convert the user input. Defaults to None.
Returns:
typing.Union[T, str]: The converted user input.
"""
while True:
value = input(message)
if converter is not None:
try:
value_converted = converter(value)
except ValueError:
print("Invalid value")
continue
else:
value_converted = typing.cast(T, value)
if possible_values is None or value_converted in possible_values:
return value_converted
print("Not one of the possibilities")由于已经有了以周期为指标的所有通货膨胀率的序列,这就很容易计算累积积,甚至接受datetime.datetime对象作为参数。
import datetime
def calculate_inflation(
amount: float,
start: typing.Union[datetime.datetime, str],
end: typing.Union[datetime.datetime, str],
inflation_rates: pd.Series,
) -> typing.Tuple[float, typing.Dict[str, float]]:
inflation_over_period = inflation_rates[start:end]
return (
amount * inflation_over_period.product(),
{
str(year): amount * index
for (year, index) in inflation_over_period.cumprod().iteritems()
},
)if __name__ == "__main__":
data_file = Path("<my path>")
inflation_rates = get_inflation_rate(data_file)
start_year = get_input(
message="Enter the starting year:",
possible_values=set(inflation_rate.index.map(str)),
)
end_year = get_input(
message="Enter the ending year:",
possible_values={
year for year in inflation_rate.index.map(str) if year > start_year
},
)
amount = get_input(message="Specify the amount:", converter=float)
print(
calculate_inflation(
amount=amount,
start=start_year,
end=end_year,
inflation_rates=inflation_rates,
)
)https://codereview.stackexchange.com/questions/241046
复制相似问题