Criando o Gerenciador de Tarefas com Python e Flask
O Gerenciador de Tarefas é uma aplicação web criada com Python e Flask para auxiliar na gestão e produtividade.
O projeto possui três funcionalidades principais:
- receber uma sugestão aleatória de tarefa;
- utilizar um cronómetro para medir o tempo de uma atividade;
- calcular a média e o desvio padrão do tempo de duas tarefas.
Para construir a aplicação utilizamos:
- Python
- Flask
- HTML
- CSS
- JavaScript
- Jinja
Estrutura do projeto
Gerenciador-de-Tarefas/
│
├── backend/
│ ├── app.py
│ ├── cronometro.py
│ ├── estatisticas.py
│ └── sugestao.py
│
└── frontend/
├── templates/
│ ├── index.html
│ ├── tarefas.html
│ ├── cronometro.html
│ └── estatisticas.html
│
└── static/
└── css/
└── style.css
Passo 1: Instalando o Flask
O Flask é o framework Python utilizado para criar o servidor web da aplicação.
No terminal, execute:
pip install flask
Passo 2: Criar o sistema de sugestões
Começaremos pela funcionalidade mais simples da aplicação.
Abra o arquivo:
backend/sugestao.py
Primeiro, importe a biblioteca random:
import random
Essa biblioteca permite realizar escolhas aleatórias.
Agora crie a função:
def sugerir_tarefa():
tarefas = [
"Ler um artigo",
"Fazer um exercício de Python",
"Revisar anotações"
]
return random.choice(tarefas)
A variável tarefas armazena uma lista contendo diferentes atividades. Sempre que a função sugerir_tarefa() for executada, uma das tarefas poderá ser escolhida.
Passo 3: Criar o cronômetro
Agora vamos criar o módulo responsável por registrar o tempo das tarefas.
Abra:
backend/cronometro.py
Importe a biblioteca time:
import time
Em seguida, crie a primeira função:
def iniciar_cronometro():
return time.time()
A função time.time() retorna um valor representando o momento atual.
Esse valor será utilizado como ponto inicial do cronômetro.
Agora crie a função responsável por pausá-lo:
def pausar_cronometro(inicio):
fim = time.time()
duracao = fim - inicio
return duracao
Ou seja, subtraímos o momento em que o cronômetro foi iniciado do momento em que ele foi pausado.
O resultado representa quantos segundos transcorreram durante aquele período.
Passo 4: Criar o cálculo das estatísticas
Além de controlar o tempo das atividades, nosso Gerenciador de Tarefas permitirá comparar o tempo gasto em duas tarefas.
Abra:
backend/estatisticas.py
Importe a biblioteca math:
import math
Agora crie:
def calcular_estatisticas(tarefa1, tarefa2):
media = (tarefa1 + tarefa2) / 2
desvio_padrao = math.sqrt(
(
(tarefa1 - media) ** 2
+ (tarefa2 - media) ** 2
) / 2
)
A média é calculada somando os dois tempos e dividindo o resultado por 2. Dentro da mesma função, o projeto também calcula o desvio padrão.
Passo 5: Criar a aplicação Flask
Agora podemos conectar os módulos anteriores utilizando Flask.
Abra:
backend/app.py
Comece com as importações:
from flask import Flask, render_template, request, redirect, url_for, session
import time
import cronometro
import estatisticas
import sugestao
Como nossos arquivos HTML e CSS estão fora da pasta backend, precisamos informar ao Flask onde encontrá-los.
app = Flask(
__name__,
template_folder="../frontend/templates",
static_folder="../frontend/static"
)
Depois definimos uma chave para que o Flask possa utilizar sessões:
app.secret_key = "gerenciador-chave-desenvolvimento"
As sessões serão utilizadas principalmente para guardar o estado do cronômetro durante a navegação.
No final do arquivo app.py, encontramos:
if __name__ == "__main__":
app.run(debug=True)
Esse trecho inicia o servidor Flask quando executamos diretamente o arquivo.
Passo 6: Criar a página inicial

O endereço / representa a página inicial do sistema.
@app.route("/")
def inicio():
return render_template("index.html")
Quando o usuário acessá-la, Flask renderiza:
index.html
Na página HTML, o menu principal apresenta três opções:
A função url_for() é utilizada para gerar os endereços das rotas Flask.
Assim, a página inicial funciona como o menu principal da aplicação.
Passo 7: Criar a página de tarefas aleatórias

No backend temos a rota:
@app.route("/tarefas")
def tarefas():
return render_template(
"tarefas.html",
tarefa=None
)
Inicialmente enviamos: tarefa=None. Isso significa que nenhuma tarefa foi sorteada ainda.
Agora criamos outra rota:
@app.route("/tarefas/sugerir", methods=["POST"])
def sugerir_tarefa():
tarefa = sugestao.sugerir_tarefa()
return render_template(
"tarefas.html",
tarefa=tarefa
)
Dentro de tarefas.html, verificamos se uma tarefa foi recebida:
{% if tarefa %}
{{ tarefa }}
{% endif %}
Ao clicar no botão, uma requisição POST é enviada para a rota responsável por escolher a tarefa aleatória.
Passo 8: Criar a página de cronômetro

Agora vamos conectar o módulo cronometro.py à aplicação. A página começa verificando se existe um cronômetro ativo:
ativo = session.get("cronometro_ativo", False)
tempo_acumulado = session.get("tempo_acumulado", 0.0)
A sessão funciona como um local onde podemos manter algumas informações durante a utilização da aplicação.
Neste caso, armazenamos:
- se o cronômetro está ativo;
- o momento em que foi iniciado;
- o tempo já acumulado.
Se o cronômetro estiver ativo:
if ativo:
inicio_cronometro = session.get(
"inicio_cronometro",
time.time()
)
tempo_atual = tempo_acumulado + (
time.time() - inicio_cronometro
)
else:
tempo_atual = tempo_acumulado
Depois enviamos essas informações para a página HTML:
return render_template(
"cronometro.html",
ativo=ativo,
tempo_atual=tempo_atual
)
Para iniciar o cronômetro temos:
@app.route("/cronometro/iniciar", methods=["POST"])
def iniciar_cronometro():
if not session.get("cronometro_ativo", False):
session["inicio_cronometro"] = cronometro.iniciar_cronometro()
session["cronometro_ativo"] = True
return redirect(url_for("pagina_cronometro"))
Para iniciar o cronômetro temos:
@app.route("/cronometro/pausar", methods=["POST"])
def pausar_cronometro():
if session.get("cronometro_ativo", False):
inicio = session.get("inicio_cronometro")
acumulado = session.get("tempo_acumulado", 0.0)
if inicio is not None:
duracao = cronometro.pausar_cronometro(inicio)
session["tempo_acumulado"] = acumulado + duracao
session["cronometro_ativo"] = False
session.pop("inicio_cronometro", None)
return redirect(url_for("pagina_cronometro"))
Para zerá-lo utilizamos:
@app.route("/cronometro/zerar", methods=["POST"])
def zerar_cronometro():
session["cronometro_ativo"] = False
session["tempo_acumulado"] = 0.0
session.pop("inicio_cronometro", None)
return redirect(url_for("pagina_cronometro"))
O arquivo cronometro.html recebe os dados enviados pelo Flask. Eles são armazenados em um elemento HTML:
Depois o JavaScript recupera essas informações:
const dadosCronometro =
document.getElementById("dados-cronometro");
const ativo =
dadosCronometro.dataset.ativo === "true";
const tempoInicial =
Number(dadosCronometro.dataset.tempo);
Criamos então uma função para transformar os segundos em minutos e segundos:
function mostrarTempo(totalSegundos) {
const segundosInteiros =
Math.floor(totalSegundos);
const minutos =
Math.floor(segundosInteiros / 60);
const segundos =
segundosInteiros % 60;
elementoMinutos.textContent =
String(minutos).padStart(2, "0");
elementoSegundos.textContent =
String(segundos).padStart(2, "0");
}
Se o cronômetro estiver ativo, utilizamos:
setInterval(function () {
const tempoDecorrido =
(performance.now() - referencia) / 1000;
mostrarTempo(
tempoInicial + tempoDecorrido
);
}, 250);
O navegador atualiza a visualização do cronômetro várias vezes por segundo, enquanto o valor principal continua sendo controlado pelo backend.
Passo 9: Criar a página de estatísticas

Agora vamos criar a rota responsável pelos cálculos. No app.py temos:
@app.route("/estatisticas", methods=["GET", "POST"])
def pagina_estatisticas():
media = None
desvio_padrao = None
erro = None
if request.method == "POST":
try:
tarefa1 = float(request.form["tarefa1"])
tarefa2 = float(request.form["tarefa2"])
media, desvio_padrao = estatisticas.calcular_estatisticas(
tarefa1,
tarefa2
)
except (ValueError, KeyError):
erro = "Digite valores numéricos válidos."
return render_template(
"estatisticas.html",
media=media,
desvio_padrao=desvio_padrao,
erro=erro
)
GETé utilizado quando acessamos a página.POSTé utilizado quando enviamos os valores do formulário.- Os valores calculados são enviados novamente para o HTML
No arquivo estatisticas.html, criamos os campos para receber os tempos.
Tempo médio:
{% if media is not none %}
{{ media }} segundos
{% else %}
--
{% endif %}
Desvio padrão:
{% if desvio_padrao is not none %}
{{ desvio_padrao }} segundos
{% else %}
--
{% endif %}
{% if erro %}
{{ erro }}
{% endif %}
Passo 10: Criar a aparência da aplicação
Toda a estilização do projeto está concentrada em:
frontend/static/css/style.css
Primeiro existe um reset básico:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
Depois configuramos o corpo da página:
body {
min-height: 100vh;
background-color: #f4f4f4;
font-family: "Inter", Arial, sans-serif;
display: flex;
justify-content: center;
}
O conteúdo principal utiliza um fundo em gradiente:
.principal {
background:
linear-gradient(
180deg,
#17112d 0%,
#18266f 23%,
#173cb7 58%,
#344fe6 80%,
#5b50e9 100%
);
color: white;
}
Os botões possuem formato arredondado:
.botao {
width: 205px;
min-height: 38px;
border: none;
border-radius: 999px;
background-color: #000000;
color: white;
}
.botao:hover {
transform: scale(1.025);
}
Tornando o layout responsivo:
@media (max-width: 430px) {
.pagina {
max-width: none;
padding: 0;
}
.principal {
min-height: 100vh;
max-height: none;
}
}
@media (max-height: 720px) {
.titulo-principal {
padding-top: 100px;
}
.menu-principal {
margin-top: 60px;
}
.cronometro-display {
margin-top: 120px;
}
}
Resultado final
Conclusão
Neste tutorial, você aprendeu como criar um Gerenciador de Tarefas com Python e Flask, separando o projeto em diferentes módulos e páginas. Criamos um sistema capaz de gerar tarefas aleatórias utilizando random, controlar o tempo utilizando time, calcular média e desvio padrão utilizando math e integrar todas essas funcionalidades através de rotas Flask. Também utilizamos templates HTML para criar as páginas da aplicação, CSS para construir uma interface responsiva e JavaScript para atualizar visualmente o cronômetro. Essa organização permite perceber como diferentes arquivos e linguagens podem trabalhar juntos na construção de uma aplicação web completa.







