Desafios - Natalnet/dataviewer-datascience GitHub Wiki

Listagem com alguns desafios de extração de dados:

Filtrar uma lista de um aluno em uma turma específica

Antes de tudo, é preciso de duas bibliotecas, a sqlAlchemy e o pandas. Notando que algumas partes do sqlAlchemy não funcionava apenas utilizando o "Import", foi preciso utilizar o "from" para importar algo específico da biblioteca. Sendo assim, as importações necessárias foram as seguintes: \

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy import text
from sqlalchemy import bindparam
import pandas as pd


A biblioteca sqlalchemy precisa de uma engine para se conectar ao banco, essa engine é passada da seguinte forma:

engine = create_engine('mysql+pymysql://usuario_do_banco:senha@localhost:porta/nomeDoBanco')

Depois, é recomendado criar uma variável para a conexão, que vai passar como atributo o conect

con = engine.connect()

A biblioteca sqlalchemy recomenda utilizar o "text" para passar as querys SQL, e é por ela que vamos fazer toda filtragem que precisamos do banco

query = text("SELECT * FROM Submission WHERE listQuestions_id = :id_list_question AND class_id = :id_class AND user_id = :id_aluno").bindparams(id_list_question = id_lista,id_class = id_classe,id_aluno = id_estudante)


Observação: o "bindparams" serve para puxar as variáveis, que vamos definir na função.
Por fim, o código fica da seguinte maneira:

def ler_alunos(id_estudante,id_lista,id_classe):
    engine = create_engine('mysql+pymysql://usuario_do_banco:senha@localhost:porta/nomeDoBanco')
    con = engine.connect()
    query = text("SELECT * FROM Submission WHERE listQuestions_id = :id_list_question AND class_id = :id_class AND user_id = :id_aluno").bindparams(id_list_question = id_lista,id_class = id_classe,id_aluno = id_estudante)
    questoes = pd.read_sql(query,con)
    con.close
    return questoes

questoes = ler_alunos(id_aluno,id_list_question,id_class)

Mostrar a quantidade de questões em uma lista de uma turma de LoP

Uma função que utilizei bastante para as análises é a nunique()
Ela é utilizada para contar valores específicos.
Por exemplo, se utilizarmos questoes.nunique(), sendo questoes o dataframe, vamos ter como retorno o número de valores diferentes dentro de cada coluna.
Então, definindo df = questoes e quisermos a quantidade de questoes, basta especificar a coluna, ficando desta maneira:

df.question_id.nunique()

Considerando um estudante de uma turma em uma lista de exercício no LoP

Observação: use a última submissão de cada questão.

Mostrar a quantidade total de submissões

Semelhante a forma que encontramos a quantidade de questões, para as submissões será da mesma maneira.
Como filtramos uma lista de um aluno de uma turma específica, basta pegar a quantidade de 'id' no dataframe, ficando assim:

df.id.nunique()

Mostrar existe pelo menos uma submissão

Observação: 0 para Não e 1 para Sim ??

Mostrar a média de acertos de questões

Para encontrar a média de acertos de questões, eu fiz utilizando todas as submissões, isto é, considerei todas as submissões do aluno para fazer a média de acertos.
Para esse caso utilizei a coluna hitPercentage que tem a porcentagem de acerto por questão em casa submissão:

df.hitPercentage.mean()

Mostrar a quantidade de submissões totalmente erradas

A quantidade de submissões totalmente erradas também vai utilizar a mesma coluna do desafio anterior. \ Com a diferença que vamos inserir um condicional.
Uma forma de selecionar algo específico de uma coluna que queremos utilizar, é usando a função query()
Então seguindo com esse raciocínio, o código ficou assim:

df.query('hitPercentage == 0')

Mostrar a quantidade de submissões parcialmente corretas

A quantidade de submissões parcialmente corretas foi dado da mesma forma do desafio passado, sendo a única diferença a seleção que fazemos dentro da função query()

parcialmente_erradas = df.query('hitPercentage > 0 and hitPercentage < 100')

Mostrar a quantidade de submissões completamente corretas

Aqui, utilizei também a função query() do pandas:

totalmente_certas = df.query('hitPercentage == 100')

Mostrar o tempo total gasto nas submissões

O tempo total é uma coluna que pelo que entendi, está dada em segundos, do tempo gasto de cada submissão. Utilizando a função sum() do python, podemos somar o tempo total gasto em todas as submissões:

df.timeConsuming.sum()

Mostrar a média do tempo gasto nas submissões

A média, podemos usar a função do Pandas mean():

df.timeConsuming.mean()

Mostrar o desvio padrão do tempo gasto nas submissões

O desvio padrão é dado pela função std()

df.timeConsuming.std()

Observação
No Pandas, temos a seguinte função: .describe()
Com ela, temos os dados como quantidade de dados, média dos dados, desvio padrão, máximos, mínimos e assim por diante.

Mostrar o percentual de questões totalmente certas da lista

Para fazer o percentual de questões totalmente certas da lista, temos que ter a quantidade de questões que o aluno acertou baseando no número de questões.
Pode acontecer do estudante ter 7 submissões corretas, mas 5 questões na lista, então para pegar apenas as maiores notas de cada questão, eu defini uma variável para os acertos:

acertos = df.nlargest(numero_de_questoes, ['hitPercentage'])
numero_de_acertos = acertos.id.nunique()

Observação: O nlargest recebe como parâmetro um número, e pega daquela colunam apenas os maiores números.
Neste caso utilizei, pois peguei anteriormente o número de questões, e coloquei para filtrar os maiores números, sendo assim, não tem risco de pegar uma questão repetida.
Depois de fazer isso, vamos fazer o mesmo para o número de questões:

numero_de_questoes = df.question_id.nunique()

Depois disso, eu criei uma função para calcular, mas pode também ser feita de maneira direta. No final, meu código ficou da seguinte maneira:

def questoes_certas_percentual(acertos,questoes):
    percentual = ((acertos*100)/questoes)
    return percentual
questoes_certas_percentual(numero_de_acertos,numero_de_questoes)

Quantidade de submissões em um dia de uma turma

Para pegar as submissões de um dia podemos fazer de duas formas. A primeira é importando todos os dados para o python e depois filtrar e utilizar a biblioteca datetime para filtrar a data.

A segunda foi como eu fiz, utilizando o comando "LIKE" no comando MySql. Com esse comando posso colocar apenas uma parte da string e ele vai filtrar todas strings que tem esse texto, neste caso vamos filtrar pela data.

O Código ficaria assim:

def submissoes_por_dia(id_classe,dia):
    engine = create_engine('mysql+pymysql://root:admin@localhost:3306/lop2teste')
    con = engine.connect()
    query = text("SELECT id FROM lop2teste.submission where createdAt LIKE :data and class_id = :classe").bindparams(data = dia, classe = id_classe)
    submissoes = pd.read_sql(query,con)
    con.close
    return submissoes

Depois de ter o dataFrame com as submissões por dia, basta ver o tamanho dele, ou apenas utilizar o .shape do pandas para ver a quantidade de linhas:

submissao_turma_dia = submissoes_por_dia(classe,data)
len(submissao_turma_dia)
submissao_turma_dia.shape

Quantidade de submissões em um dia de um estudante

Semelhante a pegar as submissões de um dia de uma classe, vamos utilizar também a tabela de submissões, com a diferença que vamos acrescentar o filtro por user_id também. Então o código vai ficar assim:

def submissoes_por_dia_estudante(id_classe,dia,id_user):
    engine = create_engine('mysql+pymysql://root:admin@localhost:3306/lop2teste')
    con = engine.connect()
    query = text("SELECT id FROM lop2teste.submission where createdAt LIKE :data and class_id = :classe and user_id = :id_user").bindparams(data = dia, classe = id_classe,id_user = id_user)
    submissoes = pd.read_sql(query,con)
    con.close
    return submissoes

E para ver a quantidade vai ser exatamente como fizemos na hora de pegar por classe, basta utilizar o comando "len"

submissao_aluno_dia = submissoes_por_dia_estudante(classe,data,estudante)
len(submissao_aluno_dia)

Listas de Exercícios da Turma

Desempenho de um aluno em uma lista

Análise considerando questões da lista Exemplo:

  • Nome da lista XXX, quantidade de questões certas, quantidade com acerto parcial, quantidade de questões erradas, quantidade de questões não fez

Desempenho de um aluno em cada lista

Use "Desempenho de um aluno em uma lista" como base

Desempenho da turma em cada lista

Use o desempenho de um aluno em todas as listas para realizar a soma de questões certas, soma das questões com acerto parcial, soma de questões erradas, soma das questões sem repostas

Desempenho de um aluno em um assunto

Desempenho de um aluno em cada assunto

Desempenho da turma em cada assunto