-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
116 lines (100 loc) · 4.77 KB
/
app.py
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
import streamlit as st
import plotly.graph_objects as go
import calendar
from datetime import datetime
from streamlit_option_menu import option_menu
import database as db # Local Import
# --- Settings------------------------------------------------
incomes = ["Salary", "Blog", "Other Income"]
expenses = ["Rent", "Food", "Utlilties", "Groceries", "Car", "Other Expenses"]
currency = "USD"
page_title = "Income and Expenses Tracker"
page_icon = "📈"
layout = "centered"
# ----------------------------------------------
st.set_page_config(page_title=page_title, page_icon=page_icon, layout=layout)
st.title(page_title + " " + page_icon)
# --- Drop Down Values for Selecting the period----------------
years = [datetime.today().year, datetime.today().year + 1]
months = list(calendar.month_name[1:])
# -- Database Interface ---------------------------------------
def get_all_periods():
items = db.fetch_all_periods()
periods = [item["key"] for item in items]
return periods
# -- Hide Streamlit style--------------------------------------
hide_menu_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
"""
st.markdown(hide_menu_style, unsafe_allow_html=True)
# --Navigation Menu -------------------------------------------
selected = option_menu(menu_title=None,
menu_icon="menu-app",
options=["Data Entry","Data Visualization"],
icons=["pencil-fill", "bar-chart-fill"], # https://icons.getbootstrap.com/
orientation="horizontal")
# --- Input and save periods-----------------------------------
if selected == "Data Entry":
st.header(f"Data Entry in {currency}")
with st.form("entry_form", clear_on_submit=True):
col1, col2 = st.columns(2)
col1.selectbox("Select Month:", months, key="month")
col2.selectbox("Select Year:", years, key="year")
"---"
with st.expander("Income"):
for income in incomes:
st.number_input(f"{income}:", min_value=0, format="%i", step=10, key=income)
with st.expander("Expenses"):
for expense in expenses:
st.number_input(
f"{expense}:", min_value=0, format="%i", step=10, key=expense
)
with st.expander("Comment"):
comment = st.text_area("", placeholder="Enter a comment here ...")
"---"
submitted = st.form_submit_button("Save Data")
if submitted:
period = str(st.session_state["year"]) + "_" + str(st.session_state["month"])
incomes = {income: st.session_state[income] for income in incomes}
expenses = {expense: st.session_state[expense] for expense in expenses}
db.insert_period(period,incomes,expenses,comment)
st.success("Data saved!")
# -- Plot Periods --------------------------------------------
if selected == "Data Visualization":
st.header("Data Visualization")
with st.form("saved_periods"):
# Todo: Get Periods from database
period = st.selectbox("Select Period:", get_all_periods())
submitted = st.form_submit_button("Plot Period")
if submitted:
# TODO: Get data from database
period_data = db.get_period(period)
comment = period_data.get("comment")
expenses = period_data.get("expenses")
incomes = period_data.get("incomes")
# Create metrics
total_income = sum(incomes.values())
total_expense = sum(expenses.values())
remaining_budget = total_income - total_expense
col1, col2, col3 = st.columns(3)
col1.metric("Total Income", f"{total_income} {currency}")
col2.metric("Total Expenses", f" {total_expense} {currency}")
col3.metric("Remaining Budget", f"{remaining_budget} {currency}")
st.text(f"Comment: {comment}")
# Create Sankey Chart
label = list(incomes.keys()) + ["Total Incomes"] + list(expenses.keys())
source = list(range(len(incomes))) + [len(incomes)]*len(expenses)
target = [len(incomes)]*len(incomes) + [label.index(expense) for expense in expenses.keys()]
value = list(incomes.values()) + list(expenses.values())
# Data to dict, dict to sankey
link = dict(source=source, target=target, value=value)
node = dict(label=label, pad=20, thickness=30, color="#E694FF")
data = go.Sankey(link=link, node=node)
# Plot it !
fig = go.Figure(data)
fig.update_layout(margin=dict(l=0, r=0, t=5, b=5))
st.plotly_chart(fig, use_container_width=True)