agroplan-ai-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,487 @@
1
+ from core.loader import carregar_dados
2
+ from core.planner import gerar_plano_inteligente, gerar_cenarios, gerar_plano_genetico
3
+ from core.scenario_simulator import recomendar_melhor_cenario
4
+ from core.bruteforce_validator import comparar_ag_com_forca_bruta, executar_multiplas_rodadas
5
+ from core.report_generator import gerar_relatorio_completo
6
+
7
+ def exibir_plano_detalhado():
8
+ """Modo 1: Exibe análise detalhada com ranking completo"""
9
+ print("=" * 80)
10
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
11
+ print(" Fase 1.5: Analisador de Terreno com Pontuação de Culturas")
12
+ print("=" * 80)
13
+ print()
14
+
15
+ # Carrega dados
16
+ print("📊 Carregando dados...")
17
+ culturas, talhoes, regras = carregar_dados()
18
+ print(f"✅ {len(culturas)} culturas carregadas")
19
+ print(f"✅ {len(talhoes)} talhões carregados")
20
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
21
+ print()
22
+
23
+ # Gera plano de plantio inteligente
24
+ print("🧠 Analisando terrenos e gerando recomendações...")
25
+ plano = gerar_plano_inteligente(culturas, talhoes, regras)
26
+ print()
27
+
28
+ # Exibe resultados detalhados
29
+ print("=" * 80)
30
+ print("📋 ANÁLISE COMPLETA E RECOMENDAÇÕES")
31
+ print("=" * 80)
32
+
33
+ lucro_total = 0
34
+ area_total = 0
35
+ risco_ponderado = 0
36
+
37
+ for p in plano:
38
+ print()
39
+ print("─" * 80)
40
+ print(f"🌾 TALHÃO {p['talhao']} — {p['area']} ha")
41
+ print(f" Características: Solo {p['solo']} | Clima {p['clima']} | "
42
+ f"Relevo {p['relevo']} | Água {p['agua']}")
43
+ print()
44
+
45
+ # Ranking de culturas
46
+ print(" 📊 RANKING DE CULTURAS:")
47
+ for i, cultura in enumerate(p['ranking'][:5], 1): # Top 5
48
+ emoji = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else " "
49
+ print(f" {emoji} {i}º {cultura['cultura'].upper():10} — "
50
+ f"Nota: {cultura['nota']:5.2f} | "
51
+ f"Lucro: R$ {cultura['lucro_total']:>10,.2f} | "
52
+ f"Risco: {cultura['risco']}%")
53
+
54
+ print()
55
+ print(f" ✅ RECOMENDAÇÃO: Plantar {p['cultura_recomendada'].upper()}")
56
+ print(f" Nota final: {p['nota']:.2f}")
57
+ print(f" 💰 Lucro estimado: R$ {p['lucro_estimado']:,.2f}")
58
+ print(f" ⚠️ Risco: {p['risco']}%")
59
+ print(f" ⏱️ Tempo de colheita: {p['tempo']} dias")
60
+ print()
61
+ print(f" 💡 JUSTIFICATIVA:")
62
+ print(f" {p['justificativa']}")
63
+
64
+ lucro_total += p['lucro_estimado']
65
+ area_total += p['area']
66
+ risco_ponderado += p['risco'] * p['area']
67
+
68
+ risco_medio = risco_ponderado / area_total if area_total > 0 else 0
69
+
70
+ print()
71
+ print("=" * 80)
72
+ print("📈 RESUMO DO PLANO")
73
+ print("=" * 80)
74
+ print(f"💵 Lucro total estimado: R$ {lucro_total:,.2f}")
75
+ print(f"⚠️ Risco médio ponderado: {risco_medio:.1f}%")
76
+ print(f"🌾 Talhões planejados: {len(plano)}")
77
+ print(f"📏 Área total: {area_total} ha")
78
+ print("=" * 80)
79
+
80
+
81
+ def exibir_simulacao_cenarios():
82
+ """Modo 2: Exibe comparação entre diferentes cenários"""
83
+ print("=" * 80)
84
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
85
+ print(" Fase 2: Simulador de Cenários")
86
+ print("=" * 80)
87
+ print()
88
+
89
+ # Carrega dados
90
+ print("📊 Carregando dados...")
91
+ culturas, talhoes, regras = carregar_dados()
92
+ print(f"✅ {len(culturas)} culturas carregadas")
93
+ print(f"✅ {len(talhoes)} talhões carregados")
94
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
95
+ print()
96
+
97
+ # Gera cenários
98
+ print("🧠 Simulando diferentes cenários de planejamento...")
99
+ cenarios = gerar_cenarios(culturas, talhoes, regras)
100
+ print()
101
+
102
+ # Exibe comparação de cenários
103
+ print("=" * 80)
104
+ print("📊 SIMULAÇÃO DE CENÁRIOS")
105
+ print("=" * 80)
106
+ print()
107
+
108
+ ordem_cenarios = ['equilibrado', 'maximo_lucro', 'baixo_risco', 'sustentavel', 'conservador']
109
+
110
+ for key in ordem_cenarios:
111
+ cenario = cenarios[key]
112
+
113
+ print("─" * 80)
114
+ print(f"🎯 CENÁRIO: {cenario['nome'].upper()}")
115
+ print(f" {cenario['descricao']}")
116
+ print()
117
+ print(f" 💰 Lucro total: R$ {cenario['lucro_total']:,.2f}")
118
+ print(f" ⚠️ Risco médio ponderado: {cenario['risco_medio']:.1f}%")
119
+ print(f" 📏 Área total: {cenario['area_total']} ha")
120
+ print()
121
+ print(" 🌾 Plano de plantio:")
122
+
123
+ for p in cenario['plano']:
124
+ print(f" Talhão {p['talhao']} ({p['area']} ha) → {p['cultura'].upper()} "
125
+ f"(Lucro: R$ {p['lucro_estimado']:,.2f} | Risco: {p['risco']}%)")
126
+
127
+ print()
128
+
129
+ # Recomendação do sistema
130
+ print("=" * 80)
131
+ print("✨ MELHOR CENÁRIO RECOMENDADO")
132
+ print("=" * 80)
133
+ print()
134
+
135
+ recomendacao = recomendar_melhor_cenario(cenarios)
136
+ cenario_recomendado = cenarios[recomendacao['cenario']]
137
+
138
+ print(f"🏆 Cenário: {cenario_recomendado['nome'].upper()}")
139
+ print()
140
+ print(f"💡 Justificativa:")
141
+ print(f" {recomendacao['justificativa']}")
142
+ print()
143
+ print("=" * 80)
144
+
145
+ # Tabela comparativa
146
+ print()
147
+ print("📊 TABELA COMPARATIVA")
148
+ print("=" * 80)
149
+ print(f"{'Cenário':<20} {'Lucro Total':>20} {'Risco Médio':>15}")
150
+ print("─" * 80)
151
+
152
+ for key in ordem_cenarios:
153
+ cenario = cenarios[key]
154
+ emoji = "🏆 " if key == recomendacao['cenario'] else " "
155
+ print(f"{emoji}{cenario['nome']:<17} R$ {cenario['lucro_total']:>15,.2f} {cenario['risco_medio']:>13.1f}%")
156
+
157
+ print("=" * 80)
158
+
159
+
160
+ def exibir_otimizacao_genetica(objetivo='equilibrado'):
161
+ """Modo 3: Exibe otimização com Algoritmo Genético"""
162
+ print("=" * 80)
163
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
164
+ print(" Fase 3: Otimizador com Algoritmo Genético")
165
+ print("=" * 80)
166
+ print()
167
+
168
+ # Carrega dados
169
+ print("📊 Carregando dados...")
170
+ culturas, talhoes, regras = carregar_dados()
171
+ print(f"✅ {len(culturas)} culturas carregadas")
172
+ print(f"✅ {len(talhoes)} talhões carregados")
173
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
174
+ print()
175
+
176
+ # Executa otimização genética
177
+ print(f"🧬 Executando Algoritmo Genético (objetivo: {objetivo})...")
178
+ print(" Gerando população inicial...")
179
+ print(" Evoluindo soluções...")
180
+ resultado = gerar_plano_genetico(culturas, talhoes, regras, objetivo=objetivo, geracoes=100, populacao=50)
181
+ print(" ✅ Otimização concluída!")
182
+ print()
183
+
184
+ # Exibe resultado
185
+ print("=" * 80)
186
+ print("🧬 OTIMIZAÇÃO COM ALGORITMO GENÉTICO")
187
+ print("=" * 80)
188
+ print()
189
+ print(f"🎯 Objetivo: {resultado['objetivo'].upper()}")
190
+ print(f"🔄 Gerações: {resultado['geracoes']}")
191
+ print(f"📊 Fitness final: {resultado['fitness']:.2f}")
192
+ print(f"🌾 Diversidade: {resultado['diversidade']} cultura(s) diferente(s)")
193
+ print()
194
+
195
+ print("─" * 80)
196
+ print("📋 PLANO OTIMIZADO ENCONTRADO")
197
+ print("─" * 80)
198
+ print()
199
+
200
+ for p in resultado['plano']:
201
+ print(f"🌾 Talhão {p['talhao']} — {p['area']} ha")
202
+ print(f" Características: Solo {p['solo']} | Clima {p['clima']} | "
203
+ f"Relevo {p['relevo']} | Água {p['agua']}")
204
+ print(f" 🌱 Cultura: {p['cultura'].upper()}")
205
+ print(f" 💰 Lucro estimado: R$ {p['lucro_estimado']:,.2f}")
206
+ print(f" ⚠️ Risco: {p['risco']}%")
207
+ print(f" 📊 Nota de compatibilidade: {p['nota']:.2f}")
208
+ print(f" ⏱️ Tempo de colheita: {p['tempo']} dias")
209
+ print()
210
+
211
+ print("=" * 80)
212
+ print("📈 RESUMO DO PLANO OTIMIZADO")
213
+ print("=" * 80)
214
+ print(f"💵 Lucro total: R$ {resultado['lucro_total']:,.2f}")
215
+ print(f"⚠️ Risco médio ponderado: {resultado['risco_medio']:.1f}%")
216
+ print(f"📏 Área total: {resultado['area_total']} ha")
217
+ print(f"🌾 Culturas utilizadas: {resultado['diversidade']}")
218
+ print(f"🎯 Fitness alcançado: {resultado['fitness']:.2f}")
219
+ print()
220
+ print("💡 JUSTIFICATIVA:")
221
+ print(f" {resultado['justificativa']}")
222
+ print("=" * 80)
223
+
224
+ # Comparação com cenários manuais
225
+ print()
226
+ print("=" * 80)
227
+ print("📊 COMPARAÇÃO: AG vs CENÁRIOS MANUAIS")
228
+ print("=" * 80)
229
+ print()
230
+
231
+ cenarios = gerar_cenarios(culturas, talhoes, regras)
232
+
233
+ print(f"{'Estratégia':<25} {'Lucro Total':>20} {'Risco Médio':>15} {'Método':>15}")
234
+ print("─" * 80)
235
+ print(f"{'🧬 AG ' + resultado['objetivo'].title():<25} "
236
+ f"R$ {resultado['lucro_total']:>15,.2f} "
237
+ f"{resultado['risco_medio']:>13.1f}% "
238
+ f"{'Otimizado':>15}")
239
+
240
+ ordem_cenarios = ['equilibrado', 'maximo_lucro', 'baixo_risco', 'sustentavel', 'conservador']
241
+ nomes_cenarios = {
242
+ 'equilibrado': 'Equilibrado',
243
+ 'maximo_lucro': 'Máximo Lucro',
244
+ 'baixo_risco': 'Baixo Risco',
245
+ 'sustentavel': 'Sustentável',
246
+ 'conservador': 'Conservador'
247
+ }
248
+
249
+ for key in ordem_cenarios:
250
+ cenario = cenarios[key]
251
+ print(f" {nomes_cenarios[key]:<22} "
252
+ f"R$ {cenario['lucro_total']:>15,.2f} "
253
+ f"{cenario['risco_medio']:>13.1f}% "
254
+ f"{'Manual':>15}")
255
+
256
+ print("=" * 80)
257
+
258
+
259
+ def exibir_validacao_ag(objetivo='equilibrado'):
260
+ """Modo 4: Valida AG comparando com força bruta"""
261
+ print("=" * 80)
262
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
263
+ print(" Fase 3.5: Validação do Algoritmo Genético")
264
+ print("=" * 80)
265
+ print()
266
+
267
+ # Carrega dados
268
+ print("📊 Carregando dados...")
269
+ culturas, talhoes, regras = carregar_dados()
270
+ print(f"✅ {len(culturas)} culturas carregadas")
271
+ print(f"✅ {len(talhoes)} talhões carregados")
272
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
273
+ print()
274
+
275
+ print(f"🔬 Validando Algoritmo Genético (objetivo: {objetivo})...")
276
+ resultado = comparar_ag_com_forca_bruta(culturas, talhoes, regras, objetivo)
277
+
278
+ if resultado.get('erro'):
279
+ print(f"\n⚠️ {resultado['mensagem']}")
280
+ return
281
+
282
+ print()
283
+ print("=" * 80)
284
+ print("🔬 VALIDAÇÃO DO ALGORITMO GENÉTICO")
285
+ print("=" * 80)
286
+ print()
287
+ print(f"🎯 Objetivo: {objetivo.upper()}")
288
+ print(f"🔢 Total de combinações testadas por força bruta: {resultado['forca_bruta']['total_combinacoes']}")
289
+ print()
290
+
291
+ # Força Bruta
292
+ fb = resultado['forca_bruta']
293
+ print("─" * 80)
294
+ print("📊 MELHOR SOLUÇÃO POR FORÇA BRUTA")
295
+ print("─" * 80)
296
+ for p in fb['plano']:
297
+ print(f" Talhão {p['talhao']} → {p['cultura'].upper()}")
298
+ print()
299
+ print(f" 📊 Fitness: {fb['melhor_fitness']:.2f}")
300
+ print(f" 💰 Lucro total: R$ {fb['lucro_total']:,.2f}")
301
+ print(f" ⚠️ Risco médio: {fb['risco_medio']:.1f}%")
302
+ print(f" 🌾 Diversidade: {fb['diversidade']} cultura(s)")
303
+ print()
304
+
305
+ # AG
306
+ ag = resultado['ag']
307
+ print("─" * 80)
308
+ print("🧬 MELHOR SOLUÇÃO PELO ALGORITMO GENÉTICO")
309
+ print("─" * 80)
310
+ for p in ag['plano']:
311
+ print(f" Talhão {p['talhao']} → {p['cultura'].upper()}")
312
+ print()
313
+ print(f" 📊 Fitness: {ag['fitness']:.2f}")
314
+ print(f" 💰 Lucro total: R$ {ag['lucro_total']:,.2f}")
315
+ print(f" ⚠️ Risco médio: {ag['risco_medio']:.1f}%")
316
+ print(f" 🌾 Diversidade: {ag['diversidade']} cultura(s)")
317
+ print()
318
+
319
+ # Comparação
320
+ print("=" * 80)
321
+ print("📈 RESULTADO DA VALIDAÇÃO")
322
+ print("=" * 80)
323
+ print()
324
+ if resultado['ag_encontrou_otimo_global']:
325
+ print("✅ STATUS: O AG ENCONTROU O ÓTIMO GLOBAL")
326
+ else:
327
+ print("⚠️ STATUS: O AG NÃO ENCONTROU O ÓTIMO GLOBAL")
328
+ print()
329
+ print(f" Diferença de fitness: {resultado['diferenca_fitness']:.2f}")
330
+ print(f" Diferença de lucro: R$ {resultado['diferenca_lucro']:,.2f}")
331
+ print()
332
+ print("💡 ANÁLISE:")
333
+ print(f" {resultado['analise']}")
334
+ print()
335
+ print("=" * 80)
336
+
337
+
338
+ def exibir_multiplas_rodadas(objetivo='equilibrado', rodadas=10):
339
+ """Modo 5: Executa AG múltiplas vezes para avaliar estabilidade"""
340
+ print("=" * 80)
341
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
342
+ print(" Fase 3.5: Análise de Estabilidade do AG")
343
+ print("=" * 80)
344
+ print()
345
+
346
+ # Carrega dados
347
+ print("📊 Carregando dados...")
348
+ culturas, talhoes, regras = carregar_dados()
349
+ print(f"✅ {len(culturas)} culturas carregadas")
350
+ print(f"✅ {len(talhoes)} talhões carregados")
351
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
352
+ print()
353
+
354
+ print(f"🔄 Executando {rodadas} rodadas do AG (objetivo: {objetivo})...")
355
+ print()
356
+ resultado = executar_multiplas_rodadas(culturas, talhoes, regras, objetivo, rodadas)
357
+ print()
358
+
359
+ print("=" * 80)
360
+ print("📊 ANÁLISE DE ESTABILIDADE DO ALGORITMO GENÉTICO")
361
+ print("=" * 80)
362
+ print()
363
+ print(f"🎯 Objetivo: {objetivo.upper()}")
364
+ print(f"🔄 Rodadas executadas: {resultado['rodadas']}")
365
+ print()
366
+ print("─" * 80)
367
+ print("📈 ESTATÍSTICAS DE FITNESS")
368
+ print("─" * 80)
369
+ print(f" 🏆 Melhor fitness: {resultado['melhor_fitness']:.2f}")
370
+ print(f" 📊 Fitness médio: {resultado['fitness_medio']:.2f}")
371
+ print(f" 📉 Pior fitness: {resultado['pior_fitness']:.2f}")
372
+ print(f" 📏 Desvio padrão: {resultado['desvio_padrao']:.2f}")
373
+ print(f" 📐 Coeficiente de variação: {resultado['coeficiente_variacao']:.2f}%")
374
+ print()
375
+ print(f" 💰 Lucro médio: R$ {resultado['lucro_medio']:,.2f}")
376
+ print(f" ⚠️ Risco médio: {resultado['risco_medio']:.1f}%")
377
+ print()
378
+
379
+ # Estabilidade
380
+ emoji_estabilidade = "🟢" if resultado['estabilidade'] == 'alta' else "🟡" if resultado['estabilidade'] == 'média' else "🔴"
381
+ print("─" * 80)
382
+ print(f"{emoji_estabilidade} ESTABILIDADE: {resultado['estabilidade'].upper()}")
383
+ print("─" * 80)
384
+ print(f" {resultado['estabilidade_descricao']}")
385
+ print()
386
+
387
+ # Melhor plano
388
+ melhor = resultado['melhor_plano']
389
+ print("=" * 80)
390
+ print("🏆 MELHOR PLANO ENCONTRADO")
391
+ print("=" * 80)
392
+ print()
393
+ for p in melhor['plano']:
394
+ print(f" Talhão {p['talhao']} ({p['area']} ha) → {p['cultura'].upper()}")
395
+ print(f" Lucro: R$ {p['lucro_estimado']:,.2f} | Risco: {p['risco']}% | Nota: {p['nota']:.2f}")
396
+ print()
397
+ print(f" 📊 Fitness: {melhor['fitness']:.2f}")
398
+ print(f" 💰 Lucro total: R$ {melhor['lucro_total']:,.2f}")
399
+ print(f" ⚠️ Risco médio: {melhor['risco_medio']:.1f}%")
400
+ print(f" 🌾 Diversidade: {melhor['diversidade']} cultura(s)")
401
+ print()
402
+ print("=" * 80)
403
+
404
+
405
+ def gerar_relatorio(objetivo='equilibrado'):
406
+ """Modo 6: Gera relatório completo"""
407
+ print("=" * 80)
408
+ print("🌱 AgroPlan AI - Sistema Inteligente de Planejamento de Plantio")
409
+ print(" Fase 4: Geração de Relatórios")
410
+ print("=" * 80)
411
+ print()
412
+
413
+ # Carrega dados
414
+ print("📊 Carregando dados...")
415
+ culturas, talhoes, regras = carregar_dados()
416
+ print(f"✅ {len(culturas)} culturas carregadas")
417
+ print(f"✅ {len(talhoes)} talhões carregados")
418
+ print(f"✅ {len(regras)} regras de cultivo carregadas")
419
+ print()
420
+
421
+ print(f"📝 Gerando relatório completo (objetivo: {objetivo})...")
422
+ print()
423
+
424
+ # Gera relatórios em ambos os formatos
425
+ caminho_md = gerar_relatorio_completo(culturas, talhoes, regras, objetivo, formato='md')
426
+ caminho_txt = gerar_relatorio_completo(culturas, talhoes, regras, objetivo, formato='txt')
427
+
428
+ print()
429
+ print("=" * 80)
430
+ print("✅ RELATÓRIOS GERADOS COM SUCESSO")
431
+ print("=" * 80)
432
+ print()
433
+ print("📄 Arquivos criados:")
434
+ print(f" - {caminho_md}")
435
+ print(f" - {caminho_txt}")
436
+ print()
437
+ print("💡 Dica: Abra o arquivo .md em um visualizador Markdown para melhor formatação")
438
+ print("=" * 80)
439
+
440
+
441
+ def main():
442
+ """Menu principal"""
443
+ import sys
444
+
445
+ # Verifica argumentos
446
+ if len(sys.argv) > 1:
447
+ modo = sys.argv[1].lower()
448
+
449
+ if modo == 'detalhado':
450
+ exibir_plano_detalhado()
451
+ elif modo == 'genetico':
452
+ # Verifica se há objetivo específico
453
+ objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
454
+ if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
455
+ print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
456
+ objetivo = 'equilibrado'
457
+ exibir_otimizacao_genetica(objetivo)
458
+ elif modo == 'validar':
459
+ # Validação com força bruta
460
+ objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
461
+ if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
462
+ print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
463
+ objetivo = 'equilibrado'
464
+ exibir_validacao_ag(objetivo)
465
+ elif modo == 'rodadas':
466
+ # Múltiplas rodadas
467
+ objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
468
+ if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
469
+ print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
470
+ objetivo = 'equilibrado'
471
+ rodadas = int(sys.argv[3]) if len(sys.argv) > 3 else 10
472
+ exibir_multiplas_rodadas(objetivo, rodadas)
473
+ elif modo == 'relatorio':
474
+ # Geração de relatório
475
+ objetivo = sys.argv[2].lower() if len(sys.argv) > 2 else 'equilibrado'
476
+ if objetivo not in ['equilibrado', 'lucro', 'risco', 'sustentavel']:
477
+ print(f"⚠️ Objetivo '{objetivo}' inválido. Usando 'equilibrado'.")
478
+ objetivo = 'equilibrado'
479
+ gerar_relatorio(objetivo)
480
+ else:
481
+ exibir_simulacao_cenarios()
482
+ else:
483
+ exibir_simulacao_cenarios()
484
+
485
+
486
+ if __name__ == "__main__":
487
+ main()
@@ -0,0 +1 @@
1
+ # Pasta para relatórios gerados
@@ -0,0 +1,6 @@
1
+ pandas>=2.0.0
2
+ scikit-learn>=1.3.0
3
+ pygad>=3.0.0
4
+ fastapi>=0.104.0
5
+ uvicorn[standard]>=0.24.0
6
+ python-multipart>=0.0.6