-
Notifications
You must be signed in to change notification settings - Fork 0
/
budget.py
146 lines (123 loc) · 5.1 KB
/
budget.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Spend tracker
# Alex Malerba (afm433)
import pandas
import plotly
import plotly.graph_objs as go
def to_usd(my_price):
"""
Converts a numeric value to usd-formatted string, for printing and display purposes.
Param: my_price (int or float) like 4000.444444
Example: to_usd(4000.444444)
Returns: $4,000.44
"""
return f"${my_price:,.2f}" #> $12,000.71
# Create or input pandas DataFrame from the input data
# https://www.geeksforgeeks.org/different-ways-to-create-pandas-dataframe/
while True:
input_method = input("What is your input method? ('csv' or 'manual'):")
if input_method == "csv":
data = pandas.read_csv("my_spend.csv", engine='python')
data["price"] = [float(p) for p in data["price"]]
break
elif input_method == "manual":
my_spend = []
done = "No"
while done == "No":
# item
input_item = input("Input your item:")
# category
input_category = input("Input the category:")
if input_category not in ["housing", "food", "transportation", "personal"]:
input_category = "other"
# price
while True:
input_price = input("Input the price:")
try:
if float(input_price) > 0:
break
else:
print("Invalid input. Price must be numbers greater than 0.")
except:
print("Invalid input. Price must be numbers greater than 0.")
# month
while True:
input_month = input("Input the month (as a number):")
try:
if (int(input_month) >=1 and int(input_month) <=12):
break
else:
print("Invalid input. Month must be between 1 and 12, inclusive.")
except:
print("Month must be between 1 and 12, inclusive.")
input_done = input("Are you done entering your spending? ('Yes' or 'No'):")
input_dict = dict({"item":input_item, "category":input_category,
"price": float(input_price), "month":input_month})
my_spend.append(input_dict)
if input_done == "Yes":
done = "Yes"
break
items = [purchase["item"] for purchase in my_spend]
categories = [purchase["category"] for purchase in my_spend]
prices = [float(purchase["price"]) for purchase in my_spend]
months = [purchase["month"] for purchase in my_spend]
data = pandas.DataFrame({"item": items, "category": categories,
"price": prices, "month": months})
if done == "Yes": # need additional check to break out of outer loop
break
else:
print("Invalid entry. You must select either 'csv' or 'manual.")
## Generate summary graphs & plots
data_by_category = data.groupby("category").sum().sort_values(by=["price"], ascending=False)
total = sum(data_by_category["price"])
data_by_date = data.groupby("month").sum().sort_values(by=["month"], ascending=True)
# Line graph over time
y = list(data_by_date["price"])
x = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Oct", "Nov", "Dec"]
print("----------------")
print("GENERATING LINE GRAPH...")
line = go.Scatter(x = x, y = y)
layout = go.Layout(title = f"Spending by Month",
xaxis = dict({"title" : "Month"}),
yaxis = dict({"title" : "Sales (USD)",
"tickformat":"$.2f"}))
plotly.offline.plot({"data": line,
"layout": layout},
filename = "spending_by_month.html",
auto_open = True)
# Pie chart showing spend by category
# Use exceptions in case there are no items in that category
try:
spend_housing = data_by_category["price"].loc["housing"]/total
except:
spend_housing = 0
try:
spend_food = data_by_category["price"].loc["food"]/total
except:
spend_food = 0
try:
spend_personal = data_by_category["price"].loc["personal"]/total
except:
spend_personal = 0
try:
spend_transportation = data_by_category["price"].loc["transportation"]/total
except:
spend_transportation = 0
try:
spend_other = data_by_category["price"].loc["other"]/total
except:
spend_other = 0
pie_data = [
{"category": "housing", "spend_pct": spend_housing},
{"category": "food", "spend_pct": spend_food},
{"category": "personal", "spend_pct": spend_personal},
{"category": "transportation", "spend_pct": spend_transportation},
{"category": "other", "spend_pct": spend_other}
]
print("----------------")
print("GENERATING PIE CHART...")
labels = [pie_data["category"] for pie_data in pie_data]
values = [pie_data["spend_pct"] for pie_data in pie_data]
trace = go.Pie(labels=labels, values=values)#, title="Spending by Category")
layout_pie = go.Layout(title = "Spending by Category")
plotly.offline.plot({"data": trace,
"layout": layout_pie}, filename="spending_by_category.html", auto_open=True)