File size: 6,829 Bytes
b54df69 3cddf46 771a15e 3cddf46 b54df69 3cddf46 b54df69 d6e934d b54df69 3cddf46 b54df69 3cddf46 d6e934d b54df69 d6e934d b54df69 d6e934d b54df69 d6e934d b54df69 d6e934d b54df69 d6e934d 3cddf46 d6e934d 2532ae2 3cddf46 bbfaf4f d6e934d b54df69 c7fc47a b54df69 771a15e d6e934d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import streamlit as st
import pandas as pd
import datetime
from transformers import AutoTokenizer, AutoModelForTableQuestionAnswering
import requests
class InterestCalculatorApp:
def __init__(self):
self.invoices_df = pd.DataFrame() # Initialize as empty DataFrame
self.base_rates_df = pd.DataFrame() # Initialize as empty DataFrame
self.late_payment_interest = st.sidebar.slider("Late Payment Interest Rate (%)", min_value=0.0, max_value=10.0, value=4.0)
self.compounding_method = st.sidebar.selectbox("Compounding Method", ["x% above Base Rate (daily)",
"x% above Base Rate (annually)",
"Quarterly compounding (25 Mar, 24 Jun, 29 Sep, 25 Dec)",
"Quarterly compounding (1 Mar, 1 Jun, 1 Sep, 1 Dec)"])
self.tokenizer = AutoTokenizer.from_pretrained("google/tapas-large-finetuned-wtq")
self.model = AutoModelForTableQuestionAnswering.from_pretrained("google/tapas-large-finetuned-wtq")
def load_invoices(self, file_path):
try:
self.invoices_df = pd.read_excel(file_path, parse_dates=['Due Date'])
st.success("Invoices loaded successfully.")
except Exception as e:
st.error(f"Failed to load invoices: {e}")
def calculate_interest(self):
if not self.invoices_df.empty and not self.base_rates_df.empty:
st.write("Calculating interest...")
today = datetime.datetime.today()
interests = []
for index, invoice in self.invoices_df.iterrows():
due_date = invoice['Due Date']
amount = invoice['Amount']
base_rate = self.get_base_rate(due_date)
effective_rate = base_rate + self.late_payment_interest
if due_date > today:
interests.append(0)
continue
interest = self.calculate_compound_interest(due_date, amount, effective_rate, self.compounding_method, today)
interests.append(interest)
total_amount_owed = amount + interest
self.invoices_df.loc[index, 'Interest'] = interest
self.invoices_df.loc[index, 'Total Amount Owed'] = total_amount_owed
total_interest = sum(interests)
st.success(f"Total Interest Calculated: £{total_interest:.2f}")
st.write(self.invoices_df)
else:
st.error("Please load both invoices and base rates files.")
def get_base_rate(self, due_date):
self.base_rates_df['Date Changed'] = pd.to_datetime(self.base_rates_df['Date Changed'])
rate_rows = self.base_rates_df[self.base_rates_df['Date Changed'] <= due_date].sort_values(by='Date Changed', ascending=False)
return rate_rows.iloc[0]['Rate'] if not rate_rows.empty else 0
def calculate_compound_interest(self, due_date, amount, effective_rate, method, today):
days = (today - due_date).days
if 'daily' in method:
daily_rate = (effective_rate / 100) / 365
return amount * daily_rate * days
elif 'annually' in method:
annual_rate = effective_rate / 100
return amount * annual_rate * (days / 365)
elif 'Quarterly compounding' in method:
return self.calculate_quarterly_interest(due_date, amount, effective_rate, method, today)
def calculate_quarterly_interest(self, due_date, amount, effective_rate, method, today):
quarterly_dates = {
"Quarterly compounding (25 Mar, 24 Jun, 29 Sep, 25 Dec)": [(3, 25), (6, 24), (9, 29), (12, 25)],
"Quarterly compounding (1 Mar, 1 Jun, 1 Sep, 1 Dec)": [(3, 1), (6, 1), (9, 1), (12, 1)]
}[method]
interest = 0
compounded_amount = amount
for month, day in quarterly_dates:
compounding_date = datetime.datetime(today.year, month, day)
if compounding_date > today:
break
if compounding_date > due_date:
days_since_last_compounding = (today - compounding_date).days
period_rate = effective_rate / 4 # Quarterly rate
compounded_interest = compounded_amount * ((1 + period_rate) ** (days_since_last_compounding / 365.25) - 1)
compounded_amount += compounded_interest
interest += compounded_interest
due_date = compounding_date
return interest
def download_boe_rates(self):
try:
headers = {
'accept-language': 'en-US,en;q=0.9',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
url = 'https://www.bankofengland.co.uk/boeapps/database/Bank-Rate.asp'
response = requests.get(url, headers=headers)
if response.status_code == 200:
df = pd.read_html(response.text)[0]
df.to_csv('boe_rates.csv', index=False)
self.base_rates_df = df
self.base_rates_df['Date Changed'] = pd.to_datetime(self.base_rates_df['Date Changed'], format='%d %b %y')
st.success("Bank of England rates downloaded successfully.")
else:
st.error("Failed to retrieve data from the Bank of England website.")
except requests.RequestException as e:
st.error(f"Failed to download rates: {e}")
def ask_tapas(self, query, table):
if not isinstance(table, pd.DataFrame):
raise TypeError("Expected the table to be a pd.DataFrame, got {}".format(type(table).__name__))
inputs = self.tokenizer(table=table, queries=[query], return_tensors="pt", padding=True)
outputs = self.model(**inputs)
predicted_answer = self.tokenizer.decode(outputs.logits.argmax(dim=-1))
return predicted_answer
def main():
st.title("Interest Calculation App")
app = InterestCalculatorApp()
file_path = st.file_uploader("Upload Invoices File", type=["xlsx"])
if file_path is not None:
app.load_invoices(file_path)
query = st.text_input("Enter your query:")
if query:
if not app.invoices_df.empty:
st.write("Invoice Data:")
st.write(app.invoices_df)
answer = app.ask_tapas(query, app.invoices_df)
st.write("Answer:", answer)
else:
st.warning("Please upload the invoices file first.")
if st.button("Calculate Interest"):
app.calculate_interest()
app.download_boe_rates()
if __name__ == "__main__":
main()
|