Pra quem caiu de para-quedas, estamos criando neste projeto atual um site sobre a covid-19. Eu já dei uma adiantada nele e o site que está online é este aqui
https://sarscov2br.herokuapp.com/ A parte do Brasil particularmente tem uns gráficos interessantes sobre as diferenças entre os estados:
Covid-19 | BrasilE é algo perto disso que estamos querendo chegar neste projeto. Não pretendo chegar ao ponto de fazer todos esses gráficos porque só aí daria mais uns 20 tópicos, mas podemos tentar fazer algo parecido nos chats se o pessoal se animar.
Hoje vamos criar o nosso segundo gráfico. No D27 criamos o gráfico abaixo, de casos novos por dia:

Agora vamos criar um algoritmo que vai somar os casos de cada dia e criar um gráfico de casos totais.
Nosso routes.py até o momento tá assim:
@app.route("/brasil")
def brazil():
# Fazendo a requisição para a API pra ter os dados da tabela
states_data_for_table = requests.get("h t t p s : / / a p i
. c o v i d 19.finspect.me/brcovid19/map").json()
# Fazendo a nova requisição para ter os casos por dia
daily_cases_data = requests.get("h t t p s : / / a p i .
c o v id19.finspect.me/brcovid19/day").json()
cases_list = list()
dates_list = list()
for daily_data in daily_cases_data:
cases_list.append(daily_data['qtd_confirmation'])
dates_list.append(daily_data['label'])
# Pegando a data atual
date = datetime.now().strftime(format="%d/%m/%Y")
return render_template("brazil.html",
table_data=states_data_for_table,
date=date,
cases_list=cases_list,
dates_list=dates_list
)
Vamos criar uma nova lista, que vai ter o número de casos cumulativos:
total_cases_list = list()
E agora vamos iterar sobre a lista de casos.
Lembrando o que ela apresenta pra gente, ela tem o número de casos novos a cada dia:
ipdb> cases_list
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418, 345, 310, 232, 482, 502, 487, 353, 323, 1138, 1119, 1076, 1146, 1222, 852, 926, 1661, 2210, 1930, 1781, 1089, 1442, 1261, 1832, 3058, 2105, 3257, 2917, 2055, 1927, 2498, 2678, 3735, 3503, 5514, 3379, 4613]
Então basta eu iterar sobre todos os elementos, salvando o número de casos do dia com o número de casos do dia anterior.
Na primeira posição da lista, vou ter 1 caso, na segunda posição, 1 caso também pois 0 + 1 = 1, depois 1 também pois 0 + 1 = 1, depois 2, pois 1 + 1 = 2 e assim sucessivamente.
E pra fazer isso precisamos criar um algoritmo.
Para isso vamos usar ferramentas que o Python já nos traz e que podem nos ajudar bastante.
Uma dessas ferramentas é a função sum, que retorna a soma de todos os elementos de uma lista:
In [1]: lista = [x for x in range(10)]
In [2]: lista
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: sum(lista)
Out[3]: 45
A outra é o laço for com um enumerate, que retorna pra gente o índice de um elemento e o elemento em si:
In [5]: lista = ['a', 'b', 'c', 'd', 'e', 'f']
In [6]: for indice, item in enumerate(lista):
...: print(indice, item)
...:
0 a
1 b
2 c
3 d
4 e
5 f
Também vou usar a ferramenta de slicing, que é o fatiamento de sequências:
In [11]: lista = [x for x in range(20)]
In [12]: lista
Out[12]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
In [13]: lista[:4]
Out[13]: [0, 1, 2, 3]
In [14]: lista[2:8]
Out[14]: [2, 3, 4, 5, 6, 7]
Então, o nosso algoritmo terá as seguintes etapas:
1 - vamos criar uma nova lista que vai receber o total de casos por dia
2 - vamos iterar pela lista de casos novos por dia usando um enumerate
3 - vamos adicionar à nossa nova lista a soma dos itens da lista original até o dia atual
O algoritmo em si vai ser assim:
In [1]: cases_list = [1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 22
...: 4, 418, 345, 310, 232, 482, 502, 487, 353, 323, 1138, 1119, 1076, 1146, 1222, 852, 926, 1661, 2210, 1
...: 930, 1781, 1089, 1442, 1261, 1832, 3058, 2105, 3257, 2917, 2055, 1927, 2498, 2678, 3735, 3503, 5514,
...: 3379, 4613]
In [2]: cases_list
Out[2]:
[1,
0,
0,
1,
0,
0,
0,
1,
4,
6,
6,
6,
0,
9,
18,
25,
21,
23,
79,
34,
57,
137,
193,
283,
224,
418,
345,
310,
232,
482,
502,
487,
353,
323,
1138,
1119,
1076,
1146,
1222,
852,
926,
1661,
2210,
1930,
1781,
1089,
1442,
1261,
1832,
3058,
2105,
3257,
2917,
2055,
1927,
2498,
2678,
3735,
3503,
5514,
3379,
4613]
In [3]: total_cases_list = list()
In [4]: for index, day in enumerate(cases_list):
...: cases_list_until_this_day = cases_list[: index + 1]
...: sum_total_cases_list_until_this_day = sum(cases_list_until_this_day)
...: total_cases_list.append(sum_total_cases_list_until_this_day)
...:
In [5]: total_cases_list
Out[5]:
[1,
1,
1,
2,
2,
2,
2,
3,
7,
13,
19,
25,
25,
34,
52,
77,
98,
121,
200,
234,
291,
428,
621,
904,
1128,
1546,
1891,
2201,
2433,
2915,
3417,
3904,
4257,
4580,
5718,
6837,
7913,
9059,
10281,
11133,
12059,
13720,
15930,
17860,
19641,
20730,
22172,
23433,
25265,
28323,
30428,
33685,
36602,
38657,
40584,
43082,
45760,
49495,
52998,
58512,
61891,
66504]
E realmente o total de casos no Brasil até o momento é de 66504 casos.
Vamos ver o algoritmo mais detalhadamente:
In [4]: for index, day in enumerate(cases_list):
...: cases_list_until_this_day = cases_list[: index + 1]
...: sum_total_cases_list_until_this_day = sum(cases_list_until_this_day)
...: total_cases_list.append(sum_total_cases_list_until_this_day)
Fatiei a solução em 3 linhas, mas poderia ter feito tudo em uma linha só. Deixei assim pra ficar mais visível.
Primeiro eu pego o resultado do fatiamento da lista. Vamos dar um print na lista fatiada pra ficar mais claro:
In [6]: for index, day in enumerate(cases_list):
...: cases_list_until_this_day = cases_list[: index + 1]
...: print(cases_list_until_this_day)
...:
[1]
[1, 0]
[1, 0, 0]
[1, 0, 0, 1]
[1, 0, 0, 1, 0]
[1, 0, 0, 1, 0, 0]
[1, 0, 0, 1, 0, 0, 0]
[1, 0, 0, 1, 0, 0, 0, 1]
[1, 0, 0, 1, 0, 0, 0, 1, 4]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418, 345]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418, 345, 310]
[1, 0, 0, 1, 0, 0, 0, 1, 4, 6, 6, 6, 0, 9, 18, 25, 21, 23, 79, 34, 57, 137, 193, 283, 224, 418, 345, 310, 232]
...
Em seguida eu somo os elementos de cada lista acima. Vamos fazer a soma e printar a soma na tela:
In [7]: for index, day in enumerate(cases_list):
...: cases_list_until_this_day = cases_list[: index + 1]
...: sum_total_cases_list_until_this_day = sum(cases_list_until_this_day)
...: print(sum_total_cases_list_until_this_day)
...:
1
1
1
2
2
2
2
3
7
13
19
25
25
34
52
77
98
121
200
234
291
428
621
904
1128
1546
1891
2201
2433
2915
3417
3904
4257
4580
5718
6837
7913
9059
10281
11133
12059
13720
15930
17860
19641
20730
22172
23433
25265
28323
30428
33685
36602
38657
40584
43082
45760
49495
52998
58512
61891
66504
Por fim eu faço o append de cada elemento desses na lista nova. E é essa lista nova que iremos passar do Flask para o JavaScript para criarmos nosso novo gráfico. Vamos atualizar parte do nosso routes.py:
cases_list = list()
dates_list = list()
total_cases_list = list()
for daily_data in daily_cases_data:
cases_list.append(daily_data['qtd_confirmation'])
dates_list.append(daily_data['label'])
for index, day in enumerate(cases_list):
total_cases_list.append(sum(cases_list[:index + 1]))
# Pegando a data atual
date = datetime.now().strftime(format="%d/%m/%Y")
return render_template("brazil.html",
table_data=states_data_for_table,
date=date,
cases_list=cases_list,
dates_list=dates_list,
total_cases_list=total_cases_list
)
Acima eu fiz a solução toda em uma linha, pois já explicamos como fazer.
Agora é tudo assunto já visto. Vamos receber os dados usando o JavaScript e criar nosso gráfico. Em nosso template, brazil.html:

Vamos ver essa nova variável para observar o que temos:

Tudo certo. Agora é só passar essa lista para um novo gráfico que vamos criar.
Vamos adicionar no template um novo canvas:
<div class="col-lg-8">
<h2>Gráficos</h2>
<div class="chart-container">
<canvas id="chart"></canvas>
</div>
<div class="chart-container">
<canvas id="chart-2"></canvas>
</div>
</div>
Com o id chart-2.
Agora no JavaScript vamos criar um novo gráfico.

Tudo isso já foi visto antes.
Vamos salvar nossos arquivos e rodar nosso servidor local com um flask run:

Pronto, criamos nosso segundo gráfico. Não mudei a cor mas vocês podem mudar a propriedade borderColor no gráfico e mudar a cor da linha.