Persano commited on
Commit
a99fa09
·
verified ·
1 Parent(s): 0168fdb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -102
app.py CHANGED
@@ -8,17 +8,17 @@ from matplotlib.ticker import FuncFormatter
8
  from xhtml2pdf import pisa
9
  from datetime import datetime
10
  import openai
11
- import traceback
12
  import logging
13
 
14
  app = Flask(__name__)
15
 
16
- # Configurar logger para console
17
  logging.basicConfig(level=logging.DEBUG)
18
 
19
  openai.api_key = os.getenv("OPENAI_API_KEY")
20
 
21
  def formatar_brl(valor):
 
22
  return f"R$ {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
23
 
24
  def gerar_analise(investimentos_finais, capital, patrimonio_studio_final):
@@ -35,25 +35,29 @@ def gerar_analise(investimentos_finais, capital, patrimonio_studio_final):
35
  return texto
36
 
37
  def gerar_analise_ia(investimentos_finais, capital, patrimonio_studio_final):
38
- prompt = f"""
39
- Faça uma análise profissional e detalhada em linguagem clara e acessível sobre os seguintes dados financeiros:
40
- - Capital inicial: R$ {capital:,.2f}
41
- - Valor patrimonial final do Studio: R$ {patrimonio_studio_final:,.2f}
42
- - Investimentos finais após 5 anos:
43
- """
44
  for nome, valor in investimentos_finais.items():
45
- prompt += f" - {nome}: R$ {valor:,.2f}\n"
46
 
47
- prompt += """
48
- Destaque qual foi o melhor investimento, o retorno percentual sobre o capital, e comente sobre possíveis estratégias e perfis de risco. Seja objetivo, claro e com tom consultivo.
49
- """
 
 
50
 
51
  resposta = openai.ChatCompletion.create(
52
  model="gpt-4o",
53
  messages=[
54
  {"role": "system", "content": "Você é um analista financeiro experiente."},
55
  {"role": "user", "content": prompt}
56
- ]
 
 
57
  )
58
  return resposta.choices[0].message.content
59
 
@@ -64,6 +68,7 @@ def render_pdf(template_src, context_dict):
64
  if not pisa_status.err:
65
  result.seek(0)
66
  return result
 
67
  return None
68
 
69
  def safe_float(valor, nome, default=0.0):
@@ -75,11 +80,58 @@ def safe_float(valor, nome, default=0.0):
75
  logging.error(f"Erro convertendo {nome} com valor '{valor}': {e}")
76
  return default
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  @app.route("/", methods=["GET", "POST"])
79
  def index():
80
  if request.method == "POST":
81
  try:
82
- # Log dos dados recebidos
83
  logging.debug(f"Dados recebidos no POST: {request.form}")
84
 
85
  capital = safe_float(request.form.get("capital"), "capital")
@@ -90,59 +142,23 @@ def index():
90
  renda_fixa = safe_float(request.form.get("renda_fixa"), "renda_fixa")
91
  inflacao = safe_float(request.form.get("inflacao"), "inflacao")
92
 
93
- anos = list(range(1, 6))
94
 
95
- patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
96
- renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
97
- studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
98
-
99
- franquia = [capital + (franquia_ret * ano) for ano in anos]
100
- acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
101
- renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
102
-
103
- dados = {
104
- "Ano": anos,
105
- "Studio (Patrimônio + Renda)": studio_total,
106
- "Franquia": franquia,
107
- "Ações": acoes,
108
- "Renda Fixa": renda_fixa_valores
109
- }
110
  df = pd.DataFrame(dados)
111
-
112
- investimentos_finais = {
113
- "Studio": studio_total[-1],
114
- "Franquia": franquia[-1],
115
- "Ações": acoes[-1],
116
- "Renda Fixa": renda_fixa_valores[-1],
117
- }
118
-
119
- plt.figure(figsize=(8, 5))
120
- plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
121
- plt.plot(anos, franquia, label="Franquia", marker="o")
122
- plt.plot(anos, acoes, label="Ações", marker="o")
123
- plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
124
- plt.title("Projeção de Investimentos (5 anos)")
125
- plt.xlabel("Ano")
126
- plt.ylabel("Valor (R$)")
127
- plt.legend()
128
- plt.grid(True)
129
- plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
130
- plt.tight_layout()
131
-
132
- buf = io.BytesIO()
133
- plt.savefig(buf, format="png")
134
- buf.seek(0)
135
- grafico_base64 = base64.b64encode(buf.getvalue()).decode("utf-8")
136
- buf.close()
137
- plt.close()
138
-
139
  df_formatado = df.copy()
140
  for col in df.columns:
141
  if col != "Ano":
142
  df_formatado[col] = df_formatado[col].apply(formatar_brl)
143
  tabela = df_formatado.to_html(index=False, classes="table table-striped table-sm text-end", border=0)
144
 
145
- analise_final = gerar_analise(investimentos_finais, capital, patrimonio_studio[-1])
 
 
 
 
 
 
 
146
 
147
  return render_template(
148
  "index.html",
@@ -171,56 +187,27 @@ def gerar_pdf():
171
  renda_fixa = safe_float(request.form.get("renda_fixa"), "renda_fixa")
172
  inflacao = safe_float(request.form.get("inflacao"), "inflacao")
173
 
174
- anos = list(range(1, 6))
175
-
176
- patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
177
- renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
178
- studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
179
- franquia = [capital + (franquia_ret * ano) for ano in anos]
180
- acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
181
- renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
182
-
183
- dados = {
184
- "Ano": anos,
185
- "Studio (Patrimônio + Renda)": studio_total,
186
- "Franquia": franquia,
187
- "Ações": acoes,
188
- "Renda Fixa": renda_fixa_valores
189
- }
190
- df = pd.DataFrame(dados)
191
-
192
- investimentos_finais = {
193
- "Studio": studio_total[-1],
194
- "Franquia": franquia[-1],
195
- "Ações": acoes[-1],
196
- "Renda Fixa": renda_fixa_valores[-1],
197
- }
198
-
199
- buf = io.BytesIO()
200
- plt.figure(figsize=(8, 5))
201
- plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
202
- plt.plot(anos, franquia, label="Franquia", marker="o")
203
- plt.plot(anos, acoes, label="Ações", marker="o")
204
- plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
205
- plt.title("Projeção de Investimentos (5 anos)")
206
- plt.xlabel("Ano")
207
- plt.ylabel("Valor (R$)")
208
- plt.legend()
209
- plt.grid(True)
210
- plt.tight_layout()
211
- plt.savefig(buf, format="png")
212
- buf.seek(0)
213
- grafico_base64 = base64.b64encode(buf.read()).decode("utf-8")
214
- buf.close()
215
- plt.close()
216
 
 
217
  df_formatado = df.copy()
218
  for col in df.columns:
219
  if col != "Ano":
220
  df_formatado[col] = df_formatado[col].apply(formatar_brl)
221
  tabela_html = df_formatado.to_html(index=False, classes="tabela", border=0)
222
 
223
- analise_final_ia = gerar_analise_ia(investimentos_finais, capital, patrimonio_studio[-1])
 
 
 
 
 
 
 
 
 
 
 
224
 
225
  context = {
226
  "capital": capital,
 
8
  from xhtml2pdf import pisa
9
  from datetime import datetime
10
  import openai
 
11
  import logging
12
 
13
  app = Flask(__name__)
14
 
15
+ # Configuração de logger
16
  logging.basicConfig(level=logging.DEBUG)
17
 
18
  openai.api_key = os.getenv("OPENAI_API_KEY")
19
 
20
  def formatar_brl(valor):
21
+ """Formata número float em string moeda BRL."""
22
  return f"R$ {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
23
 
24
  def gerar_analise(investimentos_finais, capital, patrimonio_studio_final):
 
35
  return texto
36
 
37
  def gerar_analise_ia(investimentos_finais, capital, patrimonio_studio_final):
38
+ prompt = (
39
+ f"Faça uma análise profissional e detalhada em linguagem clara e acessível sobre os seguintes dados financeiros:\n\n"
40
+ f"<strong>Capital inicial:</strong> R$ {capital:,.2f}\n"
41
+ f"<strong>Valor patrimonial final do Studio:</strong> R$ {patrimonio_studio_final:,.2f}\n"
42
+ f"<strong>Investimentos finais após 5 anos:</strong>\n"
43
+ )
44
  for nome, valor in investimentos_finais.items():
45
+ prompt += f"- {nome}: R$ {valor:,.2f}\n"
46
 
47
+ prompt += (
48
+ "\nDestaque usando <strong>negrito</strong> qual foi o melhor investimento e o retorno percentual sobre o capital. "
49
+ "Comente também sobre possíveis estratégias e perfis de risco. Use quebras de linha para organizar as ideias. "
50
+ "Seja objetivo, claro e com tom consultivo."
51
+ )
52
 
53
  resposta = openai.ChatCompletion.create(
54
  model="gpt-4o",
55
  messages=[
56
  {"role": "system", "content": "Você é um analista financeiro experiente."},
57
  {"role": "user", "content": prompt}
58
+ ],
59
+ temperature=0.7,
60
+ max_tokens=400 # reduzido para melhorar tempo de resposta
61
  )
62
  return resposta.choices[0].message.content
63
 
 
68
  if not pisa_status.err:
69
  result.seek(0)
70
  return result
71
+ logging.error(f"Erro pisa.CreatePDF: {pisa_status.err}")
72
  return None
73
 
74
  def safe_float(valor, nome, default=0.0):
 
80
  logging.error(f"Erro convertendo {nome} com valor '{valor}': {e}")
81
  return default
82
 
83
+ def calcular_projecoes(capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa):
84
+ anos = list(range(1, 6))
85
+
86
+ patrimonio_studio = [capital * ((1 + valorizacao / 100) ** ano) for ano in anos]
87
+ renda_acumulada_studio = [capital * (((1 + studio_ret / 100) ** (12 * ano)) - 1) for ano in anos]
88
+ studio_total = [p + r for p, r in zip(patrimonio_studio, renda_acumulada_studio)]
89
+
90
+ franquia = [capital + (franquia_ret * ano) for ano in anos]
91
+ acoes = [capital * ((1 + acoes_ret / 100) ** ano) for ano in anos]
92
+ renda_fixa_valores = [capital * ((1 + renda_fixa / 100) ** ano) for ano in anos]
93
+
94
+ dados = {
95
+ "Ano": anos,
96
+ "Studio (Patrimônio + Renda)": studio_total,
97
+ "Franquia": franquia,
98
+ "Ações": acoes,
99
+ "Renda Fixa": renda_fixa_valores,
100
+ }
101
+ investimentos_finais = {
102
+ "Studio": studio_total[-1],
103
+ "Franquia": franquia[-1],
104
+ "Ações": acoes[-1],
105
+ "Renda Fixa": renda_fixa_valores[-1],
106
+ }
107
+ return dados, investimentos_finais
108
+
109
+ def gerar_grafico(anos, studio_total, franquia, acoes, renda_fixa_valores):
110
+ plt.figure(figsize=(8, 5))
111
+ plt.plot(anos, studio_total, label="Studio (Patrimônio + Renda)", marker="o")
112
+ plt.plot(anos, franquia, label="Franquia", marker="o")
113
+ plt.plot(anos, acoes, label="Ações", marker="o")
114
+ plt.plot(anos, renda_fixa_valores, label="Renda Fixa", marker="o")
115
+ plt.title("Projeção de Investimentos (5 anos)")
116
+ plt.xlabel("Ano")
117
+ plt.ylabel("Valor (R$)")
118
+ plt.legend()
119
+ plt.grid(True)
120
+ plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f"R${x:,.0f}".replace(",", ".")))
121
+ plt.tight_layout()
122
+
123
+ buf = io.BytesIO()
124
+ plt.savefig(buf, format="png")
125
+ buf.seek(0)
126
+ grafico_base64 = base64.b64encode(buf.getvalue()).decode("utf-8")
127
+ buf.close()
128
+ plt.close()
129
+ return grafico_base64
130
+
131
  @app.route("/", methods=["GET", "POST"])
132
  def index():
133
  if request.method == "POST":
134
  try:
 
135
  logging.debug(f"Dados recebidos no POST: {request.form}")
136
 
137
  capital = safe_float(request.form.get("capital"), "capital")
 
142
  renda_fixa = safe_float(request.form.get("renda_fixa"), "renda_fixa")
143
  inflacao = safe_float(request.form.get("inflacao"), "inflacao")
144
 
145
+ dados, investimentos_finais = calcular_projecoes(capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa)
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  df = pd.DataFrame(dados)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  df_formatado = df.copy()
149
  for col in df.columns:
150
  if col != "Ano":
151
  df_formatado[col] = df_formatado[col].apply(formatar_brl)
152
  tabela = df_formatado.to_html(index=False, classes="table table-striped table-sm text-end", border=0)
153
 
154
+ anos = dados["Ano"]
155
+ studio_total = dados["Studio (Patrimônio + Renda)"]
156
+ franquia = dados["Franquia"]
157
+ acoes = dados["Ações"]
158
+ renda_fixa_valores = dados["Renda Fixa"]
159
+
160
+ grafico_base64 = gerar_grafico(anos, studio_total, franquia, acoes, renda_fixa_valores)
161
+ analise_final = gerar_analise(investimentos_finais, capital, studio_total[-1])
162
 
163
  return render_template(
164
  "index.html",
 
187
  renda_fixa = safe_float(request.form.get("renda_fixa"), "renda_fixa")
188
  inflacao = safe_float(request.form.get("inflacao"), "inflacao")
189
 
190
+ dados, investimentos_finais = calcular_projecoes(capital, studio_ret, valorizacao, franquia_ret, acoes_ret, renda_fixa)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
+ df = pd.DataFrame(dados)
193
  df_formatado = df.copy()
194
  for col in df.columns:
195
  if col != "Ano":
196
  df_formatado[col] = df_formatado[col].apply(formatar_brl)
197
  tabela_html = df_formatado.to_html(index=False, classes="tabela", border=0)
198
 
199
+ anos = dados["Ano"]
200
+ studio_total = dados["Studio (Patrimônio + Renda)"]
201
+
202
+ grafico_base64 = gerar_grafico(
203
+ anos,
204
+ studio_total,
205
+ dados["Franquia"],
206
+ dados["Ações"],
207
+ dados["Renda Fixa"],
208
+ )
209
+
210
+ analise_final_ia = gerar_analise_ia(investimentos_finais, capital, studio_total[-1])
211
 
212
  context = {
213
  "capital": capital,