File size: 6,199 Bytes
b54df69 |
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 |
import streamlit as st
import pandas as pd
from transformers import AutoTokenizer, AutoModelForTableQuestionAnswering
class InterestCalculatorApp:
def __init__(self):
self.invoices_df = None
self.base_rates_df = None
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)"])
# Load TAPAS model
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 self.invoices_df is not None and self.base_rates_df is not None:
st.write("Calculating interest...")
today = 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(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):
inputs = self.tokenizer(table, 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)
if st.button("Calculate Interest"):
app.calculate_interest()
app.download_boe_rates()
if __name__ == "__main__":
main()
|