Spaces:
Sleeping
Sleeping
myselfshravan
commited on
Commit
·
ac82435
1
Parent(s):
8d9c118
added mostly
Browse files- .idea/.gitignore +8 -0
- .idea/hdfc-bank-statement.iml +8 -0
- .idea/inspectionProfiles/Project_Default.xml +49 -0
- .idea/inspectionProfiles/profiles_settings.xml +6 -0
- .idea/misc.xml +4 -0
- .idea/modules.xml +8 -0
- .idea/vcs.xml +6 -0
- app.py +143 -0
- requirements.txt +13 -0
.idea/.gitignore
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Default ignored files
|
2 |
+
/shelf/
|
3 |
+
/workspace.xml
|
4 |
+
# Editor-based HTTP Client requests
|
5 |
+
/httpRequests/
|
6 |
+
# Datasource local storage ignored files
|
7 |
+
/dataSources/
|
8 |
+
/dataSources.local.xml
|
.idea/hdfc-bank-statement.iml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<module type="PYTHON_MODULE" version="4">
|
3 |
+
<component name="NewModuleRootManager">
|
4 |
+
<content url="file://$MODULE_DIR$" />
|
5 |
+
<orderEntry type="inheritedJdk" />
|
6 |
+
<orderEntry type="sourceFolder" forTests="false" />
|
7 |
+
</component>
|
8 |
+
</module>
|
.idea/inspectionProfiles/Project_Default.xml
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<component name="InspectionProjectProfileManager">
|
2 |
+
<profile version="1.0">
|
3 |
+
<option name="myName" value="Project Default" />
|
4 |
+
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
5 |
+
<Languages>
|
6 |
+
<language minSize="529" name="Python" />
|
7 |
+
</Languages>
|
8 |
+
</inspection_tool>
|
9 |
+
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
10 |
+
<option name="ignoredPackages">
|
11 |
+
<value>
|
12 |
+
<list size="4">
|
13 |
+
<item index="0" class="java.lang.String" itemvalue="beautifulsoup4" />
|
14 |
+
<item index="1" class="java.lang.String" itemvalue="pandas" />
|
15 |
+
<item index="2" class="java.lang.String" itemvalue="streamlit" />
|
16 |
+
<item index="3" class="java.lang.String" itemvalue="requests" />
|
17 |
+
</list>
|
18 |
+
</value>
|
19 |
+
</option>
|
20 |
+
</inspection_tool>
|
21 |
+
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
22 |
+
<option name="ignoredErrors">
|
23 |
+
<list>
|
24 |
+
<option value="E501" />
|
25 |
+
<option value="E701" />
|
26 |
+
<option value="W191" />
|
27 |
+
<option value="E101" />
|
28 |
+
<option value="E402" />
|
29 |
+
</list>
|
30 |
+
</option>
|
31 |
+
</inspection_tool>
|
32 |
+
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
33 |
+
<option name="ignoredErrors">
|
34 |
+
<list>
|
35 |
+
<option value="N803" />
|
36 |
+
<option value="N806" />
|
37 |
+
</list>
|
38 |
+
</option>
|
39 |
+
</inspection_tool>
|
40 |
+
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
41 |
+
<option name="ignoredIdentifiers">
|
42 |
+
<list>
|
43 |
+
<option value="sis.roll" />
|
44 |
+
<option value="list.__getitem__" />
|
45 |
+
</list>
|
46 |
+
</option>
|
47 |
+
</inspection_tool>
|
48 |
+
</profile>
|
49 |
+
</component>
|
.idea/inspectionProfiles/profiles_settings.xml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<component name="InspectionProjectProfileManager">
|
2 |
+
<settings>
|
3 |
+
<option name="USE_PROJECT_PROFILE" value="false" />
|
4 |
+
<version value="1.0" />
|
5 |
+
</settings>
|
6 |
+
</component>
|
.idea/misc.xml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (GPAEstimator2.0)" project-jdk-type="Python SDK" />
|
4 |
+
</project>
|
.idea/modules.xml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="ProjectModuleManager">
|
4 |
+
<modules>
|
5 |
+
<module fileurl="file://$PROJECT_DIR$/.idea/hdfc-bank-statement.iml" filepath="$PROJECT_DIR$/.idea/hdfc-bank-statement.iml" />
|
6 |
+
</modules>
|
7 |
+
</component>
|
8 |
+
</project>
|
.idea/vcs.xml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="VcsDirectoryMappings">
|
4 |
+
<mapping directory="" vcs="Git" />
|
5 |
+
</component>
|
6 |
+
</project>
|
app.py
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from datetime import date, datetime
|
4 |
+
import plotly.express as px
|
5 |
+
|
6 |
+
st.title('Visualize Your HDFC Bank Statement')
|
7 |
+
st.write('Export your HDFC Bank statement as a XLS file and drop it here to analyze your expenses')
|
8 |
+
st.write("Note: We don't store your data. It's all done locally on your machine")
|
9 |
+
|
10 |
+
sample_statements = ["https://github.com/myselfshravan/Python/files/10087176/statement23.xls",
|
11 |
+
"https://github.com/myselfshravan/Streamlit-Apps-Python/files/11287111/Acct.Statement_2022_Full.xls"]
|
12 |
+
agree = st.checkbox('Use Sample Statement')
|
13 |
+
if agree:
|
14 |
+
uploaded_file = st.selectbox('Select Sample Statement', sample_statements)
|
15 |
+
else:
|
16 |
+
uploaded_file = st.file_uploader("Choose a xls formate file of HDFC Bank Statement", type="xls")
|
17 |
+
|
18 |
+
if uploaded_file is not None:
|
19 |
+
df = pd.read_excel(uploaded_file)
|
20 |
+
df = df.iloc[21:-18]
|
21 |
+
df = df.drop(df.columns[[0, 2]], axis=1)
|
22 |
+
df = df.drop(df.index[1])
|
23 |
+
df = df.fillna(0)
|
24 |
+
df.rename(
|
25 |
+
columns={'Unnamed: 1': 'UPIs', 'Unnamed: 3': 'Date', 'Unnamed: 4': 'Withdrawal', 'Unnamed: 5': 'Deposited',
|
26 |
+
'Unnamed: 6': 'Balance'},
|
27 |
+
inplace=True)
|
28 |
+
|
29 |
+
df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%y').dt.date
|
30 |
+
df['Withdrawal'] = df['Withdrawal'].apply(lambda x: "{:.1f}".format(x)).astype(float)
|
31 |
+
df['Deposited'] = df['Deposited'].apply(lambda x: "{:.1f}".format(x)).astype(float)
|
32 |
+
df['Balance'] = df['Balance'].astype(float)
|
33 |
+
df['UPIs'] = df['UPIs'].astype(str)
|
34 |
+
df['UPIs'] = df['UPIs'].str.split('@', expand=True)[0]
|
35 |
+
df['UPIs'] = df['UPIs'].str.split('-', expand=True)[1]
|
36 |
+
df.index = range(1, len(df) + 1)
|
37 |
+
|
38 |
+
start_date = df['Date'].iloc[0].strftime("%B %d %Y")
|
39 |
+
end_date = df['Date'].iloc[-1].strftime("%B %d %Y")
|
40 |
+
|
41 |
+
start = datetime.strptime(df['Date'].iloc[0].strftime('%d/%m/%y'), '%d/%m/%y')
|
42 |
+
end = datetime.strptime(df['Date'].iloc[-1].strftime('%d/%m/%y'), '%d/%m/%y')
|
43 |
+
st.write(f"Statement Period: {start_date} to {end_date}")
|
44 |
+
days = (end - start).days
|
45 |
+
st.write(f"Number of Days: {days}")
|
46 |
+
total_withdrawal = df['Withdrawal'].sum()
|
47 |
+
total_deposit = df['Deposited'].sum()
|
48 |
+
st.write(f"Total Withdrawal and Deposit: Rs {total_withdrawal} - Rs {total_deposit}")
|
49 |
+
st.write(f"Closing and Opening Balance: {df['Balance'].iloc[0]} and {df['Balance'].iloc[-1]}")
|
50 |
+
st.write(f"Total Transactions: {len(df)}")
|
51 |
+
st.write(f"Average Withdrawal per day: {(total_withdrawal / days):.2f}")
|
52 |
+
st.write(f"Average Withdrawal per month: {total_withdrawal / (days / 30):.2f}")
|
53 |
+
time_frame = list(df['Date'])
|
54 |
+
withdrawal = list(df['Withdrawal'])
|
55 |
+
for i in range(1, len(withdrawal)):
|
56 |
+
withdrawal[i] = withdrawal[i] + withdrawal[i - 1]
|
57 |
+
deposited = list(df['Deposited'])
|
58 |
+
for i in range(1, len(deposited)):
|
59 |
+
deposited[i] = deposited[i] + deposited[i - 1]
|
60 |
+
|
61 |
+
balance = list(df['Balance'])
|
62 |
+
line = pd.DataFrame({'Balance': balance}, index=time_frame)
|
63 |
+
st.subheader('Balance Trend')
|
64 |
+
st.line_chart(line, use_container_width=True)
|
65 |
+
|
66 |
+
# fig = px.line(df, x='Date', y='Balance', title='Balance Trend', color_discrete_sequence=['#1f77b4'],
|
67 |
+
# template='plotly_white', labels={'Date': 'Date', 'Balance': 'Balance'},
|
68 |
+
# hover_data={'Date': False, 'Balance': ':.2f'})
|
69 |
+
# st.plotly_chart(fig, use_container_width=True)
|
70 |
+
st.dataframe(df, use_container_width=True)
|
71 |
+
|
72 |
+
val = st.radio('Select', ('Withdrawal', 'Deposited'))
|
73 |
+
if val == 'Withdrawal':
|
74 |
+
withdraw_line = pd.DataFrame({'Withdrawal': withdrawal}, index=time_frame)
|
75 |
+
st.subheader('Withdrawal Trend')
|
76 |
+
st.line_chart(withdraw_line, use_container_width=True)
|
77 |
+
fig = px.bar(df, x='Date', y='Withdrawal', title='Withdrawals')
|
78 |
+
st.plotly_chart(fig, use_container_width=True)
|
79 |
+
figs = px.scatter(df, x='Date', y='Withdrawal', color='UPIs', title='Withdrawals')
|
80 |
+
st.plotly_chart(figs, use_container_width=True)
|
81 |
+
elif val == 'Deposited':
|
82 |
+
deposit_line = pd.DataFrame({'Deposited': deposited}, index=time_frame)
|
83 |
+
st.subheader('Deposit Trend')
|
84 |
+
st.line_chart(deposit_line, use_container_width=True)
|
85 |
+
fig = px.bar(df, x='Date', y='Deposited', title='Deposits')
|
86 |
+
st.plotly_chart(fig, use_container_width=True)
|
87 |
+
figs = px.scatter(df, x='Date', y='Deposited', color='UPIs', title='Deposits')
|
88 |
+
st.plotly_chart(figs, use_container_width=True)
|
89 |
+
|
90 |
+
first_date = df['Date'].iloc[0]
|
91 |
+
date_selected = st.date_input('Select Date', value=first_date)
|
92 |
+
selected = df.loc[df['Date'] == date_selected]
|
93 |
+
st.dataframe(selected, use_container_width=True)
|
94 |
+
st.write("Total Withdrawals on", date_selected.strftime("%d %B"), "is", selected['Withdrawal'].sum())
|
95 |
+
st.write("Total Deposits on", date_selected.strftime("%d %B"), "is", selected['Deposited'].sum())
|
96 |
+
df['propdate'] = pd.to_datetime(df['Date'])
|
97 |
+
month_selected = st.selectbox('Select Month', df['propdate'].dt.strftime('%B').unique())
|
98 |
+
year = st.selectbox('Select Year', df['propdate'].dt.strftime('%Y').unique())
|
99 |
+
selected_month = df.loc[
|
100 |
+
(df['propdate'].dt.strftime('%B') == month_selected) & (df['propdate'].dt.strftime('%Y') == year)]
|
101 |
+
st.dataframe(selected_month, use_container_width=True)
|
102 |
+
st.write("Total Withdrawals in", month_selected, "is", selected_month['Withdrawal'].sum())
|
103 |
+
st.write("Total Deposits in", month_selected, "is", selected_month['Deposited'].sum())
|
104 |
+
|
105 |
+
st.write("\n")
|
106 |
+
st.subheader('Select a date range')
|
107 |
+
start_range = df['Date'].iloc[0]
|
108 |
+
end_range = df['Date'].iloc[-1]
|
109 |
+
start_date = st.date_input('Start date', value=start_range)
|
110 |
+
end_date = st.date_input('End date', value=end_range)
|
111 |
+
mask = (df['Date'] >= start_date) & (df['Date'] <= end_date)
|
112 |
+
df = df.loc[mask]
|
113 |
+
st.dataframe(df, use_container_width=True)
|
114 |
+
st.write(f'Total Deposited: Rs {df["Deposited"].sum()}')
|
115 |
+
st.write(f'Total Withdrawal: Rs {df["Withdrawal"].sum()}')
|
116 |
+
|
117 |
+
st.subheader('Total amount spent on each UPI')
|
118 |
+
st.dataframe(df.groupby('UPIs')['Withdrawal'].sum().sort_values(ascending=False), use_container_width=True)
|
119 |
+
|
120 |
+
st.subheader('Highest amount spent in one transaction')
|
121 |
+
st.dataframe(df.loc[df['Withdrawal'].idxmax()], use_container_width=True)
|
122 |
+
|
123 |
+
inday = df.groupby("Date")['Withdrawal'].sum().sort_values(ascending=False).head(1).index[0].strftime("%d %B")
|
124 |
+
st.subheader(f'Highest amount spent in a day')
|
125 |
+
amount = df.groupby("Date")['Withdrawal'].sum().sort_values(ascending=False).head(1).values[0]
|
126 |
+
st.write(f'On {inday} : Rs {amount}')
|
127 |
+
|
128 |
+
hide_streamlit_style = """
|
129 |
+
<style>
|
130 |
+
# MainMenu {visibility: hidden;}
|
131 |
+
footer {visibility: hidden;}
|
132 |
+
footer:after {
|
133 |
+
content:'Made with ❤️ by Shravan';
|
134 |
+
visibility: visible;
|
135 |
+
display: block;
|
136 |
+
position: relative;
|
137 |
+
# background-color: red;
|
138 |
+
padding: 15px;
|
139 |
+
top: 2px;
|
140 |
+
}
|
141 |
+
</style>
|
142 |
+
"""
|
143 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
requirements.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
pandas==1.4.3
|
2 |
+
streamlit==1.21.0
|
3 |
+
plotly==5.11.0
|
4 |
+
xlrd==2.0.1
|
5 |
+
beautifulsoup4==4.9.3
|
6 |
+
requests==2.25.1
|
7 |
+
requests-file==1.5.1
|
8 |
+
requests-oauthlib==1.3.1
|
9 |
+
scraper==0.1.0
|
10 |
+
selenium==3.141.0
|
11 |
+
threadpoolctl==3.1.0
|
12 |
+
typing_extensions==4.3.0
|
13 |
+
PyYAML~=6.0
|