Я думаю, что вложенные функции шумят, да.
Изменения, которые я сделал здесь:
- автоформатирование с черным
- , оборачивая основную логику в
main()
функция, позволяющая избежать использования глобалов - отмена вложения вложенных функций в свободные функции (в действительности они будут принадлежать модулю)
- рефакторинг функции, генерирующей вывод, в свободную функцию
- заставить функцию
update_form
(née some_logics
) принять поле вывода, которое она должна обновить (и фактически обновить) - исправляя немного неортодоксальное использование лямбд
Надеюсь, это поможет.
import tkinter as tk
from tkinter import scrolledtext
fields = (
"Principal",
"Expected Return",
"Number of Years",
"Yearly Payment",
"Cost Rate",
) # fields for gui
# investment return, initial investment, expected yearly return, number of years, yearly payment
def accrued(principal, rate_return, number_periods, pmt=0):
cash = principal
for periods in range(number_periods):
cash += (cash * rate_return) + pmt
return cash
# if capital is borrowed insert capital, cost of capital and number of years
def cost_of_capital(principal, rate_cost, number_periods):
effective_cost_rate = (1 + (rate_cost / 12)) ** 12 - 1
return principal * effective_cost_rate * number_periods
def calculate_output(number_periods, pmt, principal, rate_cost, rate_return):
end_cash = accrued(
principal, rate_return, number_periods, pmt
) # calculate total end sum for investment
cost_capital_end = cost_of_capital(
principal, rate_cost, number_periods
) # calculate total cost of capital
output = "\n".join(
(
f"Initial investment was {principal}, while after the period cash is {end_cash}. This is a total gain of {end_cash - principal}",
f"Of the total gain {pmt * number_periods} was coming from the installments. This results in a net gain of {end_cash - principal - (pmt * number_periods)}",
f"Cost of investment is: {cost_capital_end} and this shows a actual gain of {(end_cash - principal - (pmt * number_periods)) - cost_capital_end}",
)
)
return output
def update_form(entry_from_user, output_field):
# grab input from user from fields
principal = int(entry_from_user["Principal"].get())
rate_return = float(entry_from_user["Expected Return"].get()) / 100
number_periods = int(entry_from_user["Number of Years"].get())
pmt = int(entry_from_user["Yearly Payment"].get())
rate_cost = float(entry_from_user["Cost Rate"].get()) / 100
output = calculate_output(number_periods, pmt, principal, rate_cost, rate_return)
output_field.delete("1.0", tk.END) # clear
output_field.insert(tk.INSERT, output)
def makeform(root, fields):
# create a dictionary for fields
entries = {}
for field in fields:
row = tk.Frame(root)
lab = tk.Label(row, width=22, text=field + ": ", anchor="w")
ent = tk.Entry(row)
ent.insert(0, "0")
row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
lab.pack(side=tk.LEFT)
ent.pack(side=tk.RIGHT, expand=tk.YES, fill=tk.X)
entries[field] = ent
return entries
def main():
root = tk.Tk() # initialize object
output_field = scrolledtext.ScrolledText(root) # create output field
ents = makeform(root, fields) # create form
# create a button, button is placing user input into funcion
b1 = tk.Button(
root, text="Calculate", command=lambda: update_form(ents, output_field)
)
b1.pack(side=tk.LEFT, padx=5, pady=5)
# create a quit program button
b2 = tk.Button(root, text="Quit", command=root.quit)
b2.pack(side=tk.RIGHT, padx=5, pady=5)
# create a textfield which returns user input in format from print_out function
output_field.pack(side=tk.BOTTOM, padx=5, pady=5)
root.mainloop()
if __name__ == "__main__":
main()