Metadata-Version: 2.5
Name: inputfit
Version: 0.9.7
Summary: Análise de dados de entrada para modelos de simulação, com veredito honesto
Project-URL: Homepage, https://inputfit.streamlit.app/
Project-URL: Repository, https://github.com/genoadev/analise-dados-de-entrada
Author-email: Genoa Soluções <contato@genoads.com.br>
License: # Licença do inputfit
        
        O inputfit é distribuído sob **licenciamento dual**:
        
        1. **Uso não comercial** — gratuito, sob a PolyForm Noncommercial License
           1.0.0 (texto integral abaixo). Cobre ensino, pesquisa, uso pessoal e
           avaliação: professor em disciplina, aluno em exercício, pesquisador em
           artigo, engenheiro testando a ferramenta antes de decidir.
        
        2. **Uso comercial** — mediante licença comercial da Genoa Soluções.
           Cobre o uso no trabalho: análise de dados de entrada em projeto de
           simulação, consultoria, produto ou operação de empresa. Termos e preço
           sob consulta: **contato&#64;genoads&#46;com&#46;br** · genoads.com.br. A resposta
           padrão para um engenheiro individual é simples e rápida — escreva.
        
        Em caso de dúvida sobre qual lado se aplica ao seu uso, escreva antes de usar.
        
        ---
        
        # PolyForm Noncommercial License 1.0.0
        
        <https://polyformproject.org/licenses/noncommercial/1.0.0>
        
        ## Acceptance
        
        In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
        
        ## Copyright License
        
        The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose.  However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
        
        ## Distribution License
        
        The licensor grants you an additional copyright license to distribute copies of the software.  Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
        
        ## Notices
        
        You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software.  For example:
        
        > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
        
        ## Changes and New Works License
        
        The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
        
        ## Patent License
        
        The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
        
        ## Noncommercial Purposes
        
        Any noncommercial purpose is a permitted purpose.
        
        ## Personal Uses
        
        Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
        
        ## Noncommercial Organizations
        
        Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
        
        ## Fair Use
        
        You may have "fair use" rights for the software under the law. These terms do not limit them.
        
        ## No Other Rights
        
        These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else.  These terms do not imply any other licenses.
        
        ## Patent Defense
        
        If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
        
        ## Violations
        
        The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice.  Otherwise, all your licenses end immediately.
        
        ## No Liability
        
        ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
        
        ## Definitions
        
        The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
        
        **You** refers to the individual or entity agreeing to these terms.
        
        **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization.  **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise.  Control can be direct or indirect.
        
        **Your licenses** are all the licenses granted to you for the software under these terms.
        
        **Use** means anything you do with the software requiring one of your licenses.
License-File: LICENSE.md
Keywords: aic,anylogic,censored-data,discrete-event-simulation,distribution-fitting,input-analysis,simulation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Manufacturing
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: Portuguese (Brazilian)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.11
Requires-Dist: numpy>=1.26
Requires-Dist: pandas>=2.0
Requires-Dist: scipy>=1.11
Provides-Extra: app
Requires-Dist: openpyxl>=3.1; extra == 'app'
Requires-Dist: plotly>=5.20; extra == 'app'
Requires-Dist: streamlit>=1.40; extra == 'app'
Provides-Extra: dev
Requires-Dist: openpyxl>=3.1; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# inputfit

*English: [README.en.md](README.en.md) · Español: [README.es.md](README.es.md)*

> **English:** inputfit speaks English. Web app at
> [inputfit.streamlit.app/?lang=en](https://inputfit.streamlit.app/?lang=en);
> CLI with `--lang en`.
> **Español:** inputfit habla español. Aplicación web en
> [inputfit.streamlit.app/?lang=es](https://inputfit.streamlit.app/?lang=es);
> CLI con `--lang es`.

Dados de tempo ou duração entram, e o inputfit diz qual distribuição os descreve.
O mais importante: ele também diz quando os dados **não permitem escolher uma**.

## Comece por aqui

Escolha o jeito que cabe no seu caso:

- **No navegador, sem instalar nada.** Abra
  [inputfit.streamlit.app](https://inputfit.streamlit.app/). É uma instância pública,
  então não envie dados operacionais confidenciais. A interface fala português, inglês
  e espanhol: troque pelo seletor na barra lateral ou com `?lang=en` / `?lang=es` na URL.
- **No terminal** (Python 3.11 ou superior):

  ```bash
  pip install inputfit
  inputfit planilha.csv --col ETA
  ```

- **Com a interface web instalada no seu computador:**

  ```bash
  pip install 'inputfit[app]'
  inputfit-app
  ```

Para anexar e imprimir, peça o relatório de premissa. É um HTML autocontido de 1 a 2
páginas:

```bash
inputfit planilha.csv --col ETA --report relatorio.html
```

## Exemplo

```
$ python -m inputfit inputfit/examples/ships_demo.csv --col ETA

  ATENÇÃO: O horário 00:01:00 aparece 22 vezes em 110 registros de 'ETA'. Isso
           não é um horário, é o preenchimento de quem sabia a data e não a
           hora. Esses registros valem 'algum momento daquele dia', e é assim
           que serão tratados.

Empate técnico entre exponencial, gama e Weibull. Os dados não escolhem uma
delas.

  distribuição           AIC     ΔAIC
  exponencial         1421.0     0.00   empatada
  gama                1422.9     1.86   empatada
  Weibull             1422.9     1.92   empatada
  lognormal           1434.8    13.74   descartada

  Recomendada: exponencial  (1 parâmetro estimado)

  Para o AnyLogic:
    // exponencial de 'ETA': 109 observações, 109 como faixa
    // unidade: h   |   AIC 1421.0   |   1 parâmetro(s) estimado(s)
    exponential(0.0138933, 0)
```

A base de exemplo vem com o pacote e é **100% sintética**. Foi gerada por
`scripts/gera_demo.py`, sem nenhuma linha derivada de dado real. Ela reproduz de
propósito os problemas que a ferramenta trata: horário-sentinela, intervalo zero,
empate técnico e piso rígido. `tests/test_demo.py` garante que uma regeneração não
perde nenhum deles.

## Por que existe

Ferramentas de ajuste de distribuição costumam entregar **um vencedor com um número
de confiança ao lado**. Esse formato é o problema: a ferramenta mostra uma certeza
que os dados não sustentam.

Medido numa base portuária real de 110 chegadas:

| ferramenta | critério | vencedor |
|---|---|---|
| script original | p-valor de Kolmogorov-Smirnov | `expon` |
| `distfit` | erro sobre o histograma | `expon` |
| `fitter` | erro quadrático | `weibull_min` |
| `fitter` (coluna AIC) | AIC | `gamma` |
| **inputfit** | **AIC com verossimilhança censurada** | **empate de três** |

São quatro respostas diferentes, sem nenhum aviso. As três primeiras têm o mesmo
defeito estatístico: um p-valor de KS calculado com parâmetros estimados da própria
amostra não tem validade. Medido, o teste ingênuo rejeita 0,7% das vezes quando
deveria rejeitar 5%. Ele **aceita ajustes ruins**, e em simulação esse é o pior erro,
porque passa despercebido.

## O que ele faz e as outras não fazem

**Declara empate.** Diferença de AIC abaixo de 2 não sustenta preferência. Escolher a
de menor AIC nessa faixa seria inventar uma precisão que a amostra não tem.

**Trata registro arredondado como arredondado.** Um horário anotado como
`01/03/2018 00:01` quando só a data era conhecida não vale 00:01. Vale "algum momento
daquele dia". Cada observação entra como uma faixa e contribui `F(b) − F(a)`, em vez
da densidade pontual. A alternativa óbvia, descartar os intervalos de valor zero,
funde dois eventos num só e **derruba a taxa de chegada em 8,2%**. Num estudo de
capacidade de berço, isso decide entre recomendar e não recomendar um investimento.

**Avisa quando a coluna é saída do modelo.** Um piso rígido bem acima de zero é sinal
de restrição de capacidade. A atracação de navio tem piso porque o berço precisa
desocupar, e berço ocupado é fila, que o simulador calcula. Se você ajusta uma
distribuição a essa coluna e a realimenta no modelo, a capacidade atual passa a
fazer parte da premissa de chegada, e o modelo perde a capacidade de responder a
pergunta para a qual existe.

**Confere a ordem física entre colunas.** Chegada depois da atracação é impossível,
e nenhuma estatística detecta isso sozinha: uma distribuição ajustada a carimbos
trocados ajusta bem e engana.

## E o p-valor?

O p-valor é o critério do livro-texto de graduação. Trocá-lo por AIC não abandona a
estatística: os dois saem da mesma verossimilhança máxima e respondem perguntas
diferentes. O teste de aderência pergunta se **uma** distribuição pode ser rejeitada.
Ele não ordena candidatas, e o poder dele cresce com `n`. Com muitos dados, rejeita
tudo; com poucos, não rejeita nada. O AIC compara as candidatas entre si e cobra pela
complexidade.

Para modelos aninhados, que diferem por um parâmetro (a exponencial é a gama com forma
fixada em 1), as duas escalas fazem a mesma conta: `ΔAIC = D − 2`, sendo `D` a
estatística da razão de verossimilhanças. Na prática, preferir o modelo maior só pelo
AIC equivale a aceitar `p < 0,157`, bem mais permissivo que os 0,05 usuais. Por isso o
corte de empate em ΔAIC 2 importa: ele corresponde a `p < 0,046`. Entre famílias não
aninhadas (gama contra lognormal) não existe p-valor, e o AIC compara do mesmo jeito.

O teste de aderência continua disponível para a pergunta que o AIC não responde: a
primeira colocada presta em termos absolutos? O botão **rodar teste de aderência** da
interface web executa `gof_censored`, um Kolmogorov-Smirnov calibrado por bootstrap
paramétrico. Cada réplica sofre a mesma perda de precisão dos dados observados. É a
versão do teste sem o defeito descrito acima.

## Uso pelo terminal

Opções úteis (os nomes em português continuam aceitos):

```bash
--list-cols                          lista as colunas e sai
--list-sheets                        lista as abas do Excel
--sheet "Base Navios"                escolhe a aba
--kind duration                      duração do evento (permite piso positivo)
--dists expon gamma                  restringe as candidatas
--sequence ETA ATR ICA TCA DTR       confere a ordem física dos carimbos
--report relatorio.html              grava o relatório de premissa
--lang en                            idioma da saída (pt, en ou es)
```

Códigos de saída: `0` ajustou, `1` os dados não permitem ajuste, `2` erro de uso.
A diferença entre 1 e 2 importa. Dado que não permite ajuste é um **resultado** da
ferramenta, não um erro de chamada.

Como biblioteca:

```python
from inputfit import analyze

r = analyze(planilha["ETA"], "ETA")
r.verdict.headline          # 'Empate técnico entre gama, Weibull e exponencial...'
r.verdict.recommended.label # 'exponencial'
r.verdict.caveats           # ressalvas que devem aparecer ACIMA do resultado
```

`analyze` sempre devolve um `AnalysisResult`, nunca `None`. Dado que não se ajusta é
resultado esperado, e é justamente o que a ferramenta existe para detectar.

## Arquitetura

```
  planilha
      |
      v
  +----------+   DataFrame + relatorio de parsing
  |  io.py   |   (linha vazia != valor nao parseavel)
  +----------+
      |
      v
  +--------------+   avisos + resolucao POR OBSERVACAO
  | diagnose.py  |   sentinela de horario, piso rigido,
  +--------------+   ordem fisica entre colunas
      |
      | (veto) --------> verdict.py  "nao ajustavel, eis o porque"
      v
  +----------+   verossimilhanca censurada + AIC + aderencia
  |  fit.py  |   SO NUMEROS, nenhuma opiniao
  +----------+
      |
      v
  +-------------+   TODOS os limiares vivem aqui
  | verdict.py  |   dAIC<2, parcimonia, veto sobrepoe AIC
  +-------------+
      |
      v
  +------------+   escala -> taxa, por distribuicao
  | export.py  |
  +------------+
```

`specs.py` é o registro. Cada distribuição declara **uma vez** a restrição de ajuste,
as acumuladas em forma fechada e a parametrização do simulador de destino. Sem isso,
alguém atualizaria uma das três e esqueceria as outras, e o validador testaria um
modelo diferente do que foi ajustado, sem nenhum erro aparente.

Três fronteiras têm testes que falham se forem violadas: os limiares de decisão ficam
só em `verdict.py`, `diagnose.py` não expõe política de limpeza, e as duas interfaces
não decidem sobre exportação por conta própria.

## Testes

```bash
uv run pytest                  # 800 testes (4 pulados), ~5 min
uv run pytest -m lento         # calibração estatística, minutos
```

A calibração mede a taxa de erro tipo I com a verdade conhecida por construção. Se os
dados vêm da distribuição testada, o teste precisa rejeitar α das vezes. Medido com
400 simulações × 199 réplicas:

| dist | @0,05 | @0,10 | @0,01 |
|---|---|---|---|
| `expon` | 0,0300 | 0,0725 | 0,0025 |
| `gamma` | 0,0475 | 0,1075 | 0,0150 |
| `weibull_min` | 0,0475 | 0,1025 | 0,0075 |
| `lognorm` | 0,0275 | 0,0750 | 0,0000 |

Todas ficam a ±0,033 do nominal. Essa medição é o que sustenta a afirmação de que o
teste é honesto. Sem ela, seria só uma declaração.

## Destinos de exportação

O bloco de parâmetros sai para quatro alvos (`--target anylogic|excel|python|simul8`)
ou num **formato que você declara** (`--template "EXPO({media})"`). Cada alvo tem a
sua verificação:

- **AnyLogic.** As quatro exportações (`exponential`, `gamma`, `weibull`, `lognormal`)
  foram conferidas contra a documentação. A lognormal também foi testada na prática:
  `lognormal(0.1, 2.0, 0)` amostrada centenas de vezes deu mediana ~1,1 (= e^0,1). Só
  a assinatura `lognormal(mu, sigma, min)` produz esse resultado.
- **Python.** Verificável por construção: a saída é o próprio `scipy.stats` que o motor
  ajustou. A suíte avalia a string emitida e compara a CDF com o ajuste.
- **Excel.** Fórmulas de CDF inversa de livro-texto, espelhadas função a função e
  conferidas contra a `ppf` do scipy na suíte.
- **Simul8.** A documentação pública **não publica** as parametrizações. Por isso os
  mapeamentos saem com `verified=False` e ficam retidos atrás de `--allow-unverified`.
  A nota de cada um traz o protocolo de conferência de 30 s.
- **Formato declarado.** Não há documentação contra a qual conferir um formato que você
  mesmo declarou. Em vez de reter o bloco, a ferramenta o entrega com um glossário dos
  campos usados. Por exemplo, `{beta}` é ESCALA, não taxa, e confundir os dois é o erro
  mais caro da área.

A nota de procedência de cada mapeamento fica em `inputfit/specs.py`, com as
traduções para inglês e espanhol em `inputfit/i18n/`. Um mapeamento não conferido
nunca sai em silêncio, para nenhum alvo.

## Dados

`data/` está no `.gitignore` e nunca entra no histórico, porque guarda movimentações
portuárias reais. Os testes usam `tests/fixtures/`, que mantém a estrutura sem a
identificação. Veja `tests/fixtures/README.md`.

## Licença

Licença **dupla** (veja [LICENSE.md](LICENSE.md)):

- **Uso não comercial.** Gratuito, sob a PolyForm Noncommercial 1.0.0. Vale para ensino,
  pesquisa, uso pessoal e avaliação.
- **Uso comercial.** Projetos de simulação, consultoria, produtos ou operação de empresa
  exigem licença comercial da Genoa Soluções:
  **contato&#64;genoads&#46;com&#46;br**. Para engenheiro individual, a resposta é
  simples e rápida: escreva.
