Skip to content

Correção strict e pequenas melhorias #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Feb 27, 2021

Conversation

opardal
Copy link
Contributor

@opardal opardal commented Jan 7, 2021

Questões

1. Primeiro, um erro que cometi no PR #32

O referido PR foi elaborado em função da issue #24 .

A questão era que:

>>> sgs.dataframe([20577,20669,20745,21117,20882], start='17/08/2019', end='18/08/2019')

Retornava:

>>> 20577 20669 20745 21117 20882 2019-06-01 203887.0 11921.0 20.84 1.99 84.53

A bibiloteca herdava o comportamento da API do SGS e retornava, por padrão, o último valor armazenado para a série. O #32 corrigiu a falha para a situação específica (quando o retorno da função dataframe ou time_serie era apenas um registro):

>>> ts = sgs.time_serie(20577, start='17/08/2019', end='18/08/2019', strict=True)
WARNING: Serie 20577 - There is no data for the requested period, but there's previous data.
>>> ts
Series([], Name: 20577, dtype: float64)

Contudo, o comportamento do parametro strict=True quando as funções retornam mais de um registro não é o ideal:

>>> import sgs
>>> ts = sgs.time_serie(12,'01/05/2018','03/05/2018')
>>> ts
2018-04-30    0.024583
2018-05-02    0.024583
2018-05-03    0.024583
Name: 12, dtype: float64
>>> ts = sgs.time_serie(12,'01/05/2018','03/05/2018', True)
WARNING: Serie 12 - There is no data for the requested period, but there's previous data.

No meu entendimento, o correto deveria ser:

>>> ts = sgs.time_serie(12, '01/05/2018', '03/05/2018', True)
>>> ts
2018-05-02    0.024583
2018-05-03    0.024583
Name: 12, dtype: float64

E a mensagem deve ocorrer apenas nas situações onde não haja nenhum retorno, como por exemplo:

>>> ts = sgs.time_serie(25,'29/03/2018','01/04/2018')
>>> ts
2018-03-28    0.5
2018-04-01    0.5
Name: 25, dtype: float64
>>> ts = sgs.time_serie(25, '29/03/2018', '31/03/2018', True)
WARNING: Serie(s) 25 - There is no data for the requested period.

2. Ainda sobre a issue #24 , percebi que a galera usa a função para extrair dados de um único registro. Assim, não seria necessário ter um parâmetro end.

3. Retorno da função metadata vindo com dois tipos distintos

O dicionário resultante dessa função possui duas chaves (first_value e last_value) que retornam ora um Timestamp ora uma string. A multiplicidade de tipos retornados pode acarretar dificuldades.

>>> df = sgs.dataframe([12,4387,20577,7334], '01/05/2018', '03/05/2018')
>>> meta = sgs.metadata(df)

>>> for serie in meta:
...    print('Serie %s: %s - tipo: %s' % (serie['code'], serie['last_value'], type(serie['last_value'])))
...
Serie 12: 2021-01-04 00:00:00 - tipo: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
Serie 4387: 1º Quar. 2009 - tipo: <class 'str'>
Serie 20577: 2020-11-01 00:00:00 - tipo: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
Serie 7334: 3º Quar. 2014 - tipo: <class 'str'>

Abordagem:

Sobre o item 1:

Criação de um arquivo específico (strict.py) para a função constrain.

A função tem três parâmetros: data, start, end.

É, basicamente, um filtro por data que garante as mensagens informativas ao usuário.

Ela está por trás da funcionalidade strict da time_serie e do dataframe.

>>> import sgs

>>> ts = sgs.time_serie(12, '01/05/2018', '03/05/2018')
>>> ts
2018-04-30    0.024583
2018-05-02    0.024583
2018-05-03    0.024583
Name: 12, dtype: float64

>>> ts = sgs.time_serie(12, '01/05/2018', '03/05/2018', True)
>>> ts
2018-05-02    0.024583
2018-05-03    0.024583
Name: 12, dtype: float64

>>> df = sgs.dataframe([12,25], '01/05/2018', '03/05/2018')
>>> df
                  12   25
2018-04-30  0.024583  NaN
2018-05-01       NaN  0.5
2018-05-02  0.024583  0.5
2018-05-03  0.024583  0.5

>>> df = sgs.dataframe([12,25], '01/05/2018', '03/05/2018', True)
>>> df
                  12   25
2018-05-01       NaN  0.5
2018-05-02  0.024583  0.5
2018-05-03  0.024583  0.5

Da forma como está implementada a função, também é possível aplicar a uma time_serie ou dataframe já constituídos.

Ex.:

>>> ts = sgs.time_serie(12,'01/05/2018','03/05/2018')
>>> sgs.constrain(ts,'01/05/2018','03/05/2018')
2018-05-02    0.024583
2018-05-03    0.024583
Name: 12, dtype: float64

>>> df = sgs.dataframe([12,25], '01/05/2018', '03/05/2018')
>>> sgs.constrain(df, '01/05/2018', '03/05/2018')
                  12   25
2018-05-01       NaN  0.5
2018-05-02  0.024583  0.5
2018-05-03  0.024583  0.5

Essa implementação levou a eliminação da função get_data_with_strict_range e a simplificação do modulo api.py

Sobre o item 2:

O parametro end das funções time_serie e dataframe foram transformados em opcionais.

>>> sgs.time_serie(12, '05/05/2020')
2020-05-05    0.014227
Name: 12, dtype: float64
>>> sgs.time_serie(12, '05/05/2020', '08/05/2020')
2020-05-05    0.014227
2020-05-06    0.014227
2020-05-07    0.011345
2020-05-08    0.011345
Name: 12, dtype: float64

e

>>> sgs.dataframe([12,25], '05/05/2020')
                  12   25
2020-05-05  0.014227  0.5
>>> sgs.dataframe([12,25], '05/05/2020', '08/05/2020')
                  12   25
2020-05-05  0.014227  0.5
2020-05-06  0.014227  0.5
2020-05-07  0.011345  0.5
2020-05-08  0.011345  0.5

Sobre o item 3:

Foram alterados os arquivos metadata.py e o search.py.

Primeiramente, a função metadata foi alterada para receber time_serie, list e tuple.

Em segundo lugar, foi criada uma expansão da função to_datetime do modulo common.py: a to_datetime_string, que retorna sempre uma string.

>>> df = sgs.dataframe([12,4387,20577,7334], '01/05/2018', '03/05/2018')
>>> meta = sgs.metadata(df)
>>> for serie in meta:
...     print('Serie %s: %s - tipo: %s' % (serie['code'], serie['last_value'], type(serie['last_value'])))
... 
Serie 12: 2021-01-06 00:00:00 - tipo: <class 'str'>
Serie 4387: 1º Quar. 2009 - tipo: <class 'str'>
Serie 20577: 2020-11-01 00:00:00 - tipo: <class 'str'>
Serie 7334: 3º Quar. 2014 - tipo: <class 'str'>

Ainda dentro do modulo common.py, foi criada uma função auxiliar, chamada get_series_codes, para gerar uma lista dos códigos das séries a partir de variaveis do tipo int, list, tuple, df e series.

Por fim, e com base nas alterações acima, foram implementadas algumas refatorações nos seguintes modulos:

- metadata.py
- ts.py
- dataframe.py
- common.py
- api.py

As alterações não modificam o comportamento atual da biblioteca, apenas acrescentam funcionalidades. Apenas o tipo dos campos de data do dicionário retornado pela função metadata passam a ser string. Mas, como trata-se de metadata, creio que não tenha grande impacto.

Por último, foram desenvolvidos testes para as novas funcionalidades.

Se vocês acharem necessário, posso quebrar esse PR em menores para facilitar a análise.

rafpyprog and others added 30 commits July 4, 2019 22:08
* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst

* Updates README.rst
* Fix bug when time series search returned more than one result pages

* Fix bug when time series search returned more than one result pages

* Fix bug when time series search returned more than one result pages

* Fix bug when time series search returned more than one result pages

* Fix bug when time series search returned more than one result pages
* fix date parsing when only year is present

* fix date parsing when only year is present

* fix date parsing when only year is present
… on date time transformation

* fix date parsing when only year is present

* fix date parsing when only year is present

* fix date parsing when only year is present

* fix date parsing when only year is present
@rafpyprog rafpyprog merged commit f58efb6 into rafpyprog:develop Feb 27, 2021
@opardal
Copy link
Contributor Author

opardal commented Mar 20, 2021

Por que aqui os checks do commit f58efb6 passam e depois começam a indicar problemas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants