Rastreador de asistencia simple usando Python

En muchas universidades tenemos un sistema de asistencia para cada materia, y la falta del mismo genera problemas. Es difícil para los estudiantes recordar el número de permisos tomados para un tema en particular. Si cada vez que se tiene que hacer el papeleo para hacer un seguimiento del número de licencias tomadas por el personal y comprobar si es falta de asistencia o no, implica mucho tiempo y también es ineficiente. 

Este artículo traerá un sistema simple de seguimiento y recordatorio para la asistencia. La entrada a este sistema es una hoja de Excel que contiene la identificación de correo de los estudiantes y su número de ausencias en cada materia de clase. Por ejemplo, si a un estudiante no se le permitirá escribir el examen de una materia en particular si toma más de 3 hojas. Este rastreador enviará un correo electrónico al estudiante cuando tome la segunda licencia como recordatorio de que solo le queda 1 más sobre ese tema. Si vuelve a tomar licencia, tanto el estudiante como el personal correspondiente reciben correos electrónicos sobre la falta de asistencia. Lo único que debe hacer es ingresar el código de la materia y el número de registro del estudiante ausente de la clase y este sistema de seguimiento se encargará del resto.

Módulos de Python utilizados

Instale los siguientes módulos usando los comandos pip o conda.

  • openpyxl : para actualizar y leer desde la hoja de Excel.
  • smtplib & email   : para enviar correos electrónicos.

Conjunto de datos en uso:

La hoja de Excel debe contener los siguientes datos:

  • Número de rollo
  • ID de correo del estudiante
  • Asunto {1,2,……..N}

Para este artículo, considere tres temas y sus códigos como números de entrada: 

  • Inteligencia Informática (IC)—-> 1
  • Python —-> 2
  • Minería de datos (DM) —-> 3

Inicialmente, la hoja de Excel debería verse así:

ID de Gmail para enviar correo

Es recomendable crear una ID de correo separada para usarla como remitente, ya que Google impide que las aplicaciones menos seguras inicien sesión en Gmail. Se deben otorgar ciertos permisos para enviar el correo, lo cual es arriesgado hacerlo con una ID de correo personal. Si no otorga permisos, terminará con el error » malas credenciales » y recibirá un correo electrónico, como puede ver en la siguiente captura de pantalla:

Para evitar estos problemas, siga los pasos a continuación:

  • Iniciar sesión en su cuenta.
  • Haga clic en el ícono de perfil en la esquina superior derecha y haga clic en administrar su cuenta de Google.

  • Vaya a la pestaña de seguridad y busque la configuración de «aplicaciones menos seguras».

  • La opción de aplicaciones menos seguras se desactivará. Haz clic en “Activar acceso”.

  • Verá la siguiente pantalla y haga clic en el botón de alternar para permitir que las aplicaciones que no son de Google usen su cuenta de Gmail.

Ahora todos los requisitos previos están listos. Se debe escribir un script de Python para el seguimiento. Hagámoslo paso a paso.

Implementación paso a paso

  • Importar módulos requeridos
  • Inicialice las variables requeridas e importe el archivo de datos en uso.
  • Crear una función para guardar Excel en cada actualización

Python3

def savefile():
  
    book.save(r'<your-path>\attendance.xlsx')
    print("saved!")
  • Cree una función para rastrear la asistencia: se requiere una función para verificar la lista de ausentes contra la condición de umbral. Las actualizaciones deben realizarse a las variables declaradas fuera de la función como variables globales. Así, se escriben las siguientes líneas.

Python3

def check(no_of_days, row_num, b):
  
  # to use the globally declared lists and strings
    global staff_mails
    global l2
    global l3
  • Esta función check() toma tres argumentos:
    • no_of_days : Lista A que contiene total.no.of. hojas de los alumnos en el parámetro núm_fila.
    • row_num: una lista de números de lista de los ausentes de hoy
    • b : Código de asunto

Ejemplo : 

Si los parámetros son [1,1,2,3] , [1,2,3,4] , 1

no_of_days : [1,1,2,3] – número total de permisos hasta la fecha tomada por cada estudiante en la siguiente lista.

row_num: [1,2,3,4] – números de rollo ausentes para hoy.

b: 1 – Código de Materia: aquí Inteligencia Informática

  • Recorra la lista de estudiantes (row_num) y para cada estudiante verifique las siguientes condiciones:
    • Si el número total de hojas == umbral de advertencia
    • Si el número total de hojas > umbral de advertencia
  • Aquí, teniendo en cuenta que a un estudiante no se le permitirá hacer exámenes si toma más de 2 hojas. Por lo tanto, el umbral de advertencia es 2. Si un estudiante toma 2 permisos, incluida la ausencia de hoy, entonces se le debe enviar un correo de recordatorio, de lo contrario, se deben enviar dos correos indicando la falta de asistencia de manera que uno para el estudiante y el otro para el personal.
  • Ahora, si el número total de hojas == umbral de advertencia, agregue la identificación de correo del estudiante correspondiente a la lista ‘l1’, de lo contrario, liste ‘l3’ . Si la identificación de correo del estudiante se agrega a la lista ‘l3’ , entonces el número de registro debe agregarse a la string ‘l2’ para enviar al personal.
  • Crear funciones para el envío de correos: se crearán dos funciones, a saber, mailstu() y mailstaff() . Puede haber una lista de estudiantes a los que se les deben enviar advertencias, pero solo un miembro del personal para esa materia correspondiente. Por lo tanto, se han escrito dos métodos diferentes en consecuencia.
    • Los módulos smtplib y email.mime se utilizan para enviar el correo en este script.
    • Los correos electrónicos MIME son ampliamente utilizados ahora. Se pueden ampliar como extensiones de correo de Internet multipropósito . Permiten una combinación de texto plano y HTML en el cuerpo del correo. La API email.mime proporciona funcionalidades para estructurar correos electrónicos desde Python y también para agregar archivos adjuntos.
    • El módulo smtplib permite conectarse a un host a través de un puerto. Los puertos están predefinidos para cada dominio y su uso adecuado ayuda a establecer conexiones y enviar correo. El número de puerto para yahoo también es 587 , pero el host será smtp.mail.yahoo.com

Python3

# for students
def mailstu(li, msg):
    from_id = 'cXXXXXXXXXs@gmail.com'
    pwd = 'XXXXXXXXXXXXX'
    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.starttls()
    s.login(from_id, pwd)
  
    # for each student to warn send mail
    for i in range(0, len(li)):
        to_id = li[i]
        message = MIMEMultipart()
        message['Subject'] = 'Attendance report'
        message.attach(MIMEText(msg, 'plain'))
        content = message.as_string()
        s.sendmail(from_id, to_id, content)
        s.quit()
    print("mail sent to students")
  
# for staffs
def mailstaff(mail_id, msg):
    from_id = 'cXXXXXXXXXXs@gmail.com'
    pwd = 'XXXXXXXX'
    to_id = mail_id
    message = MIMEMultipart()
    message['Subject'] = 'Lack of attendance report'
    message.attach(MIMEText(msg, 'plain'))
    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.starttls()
    s.login(from_id, pwd)
    content = message.as_string()
    s.sendmail(from_id, to_id, content)
    s.quit()
    print('Mail Sent to staff')
  • El paso final es escribir un bucle que obtenga información de los usuarios hasta que digan que no hay más entradas.

La implementación completa siguiendo el enfoque anterior se da a continuación.

Ejemplo: rastreador de asistencia simple 

Python3

import openpyxl
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
  
# loading the excel sheet
book = openpyxl.load_workbook('D:\\attendance.xlsx')
  
# Choose the sheet
sheet = book['Sheet1']
  
# counting number of rows / students
r = sheet.max_row
  
# variable for looping for input
resp = 1
  
# counting number of columns / subjects
c = sheet.max_column
  
# list of students to remind
l1 = []
  
# to concatenate list of roll numbers with
# lack of attendance
l2 = ""
  
# list of roll numbers with lack of attendance
l3 = []
  
# staff mail ids
staff_mails = ['erakshaya485@gmail.com', 'yyyyyyyy@gmail.com']
  
# Warning messages
m1 = "warning!!! you can take only one more day leave for CI class"
m2 = "warning!!! you can take only one more day leave for python class"
m3 = "warning!!! you can take only one more day leave for DM class"
  
  
def savefile():
    book.save(r'D:\\attendance.xlsx')
    print("saved!")
  
  
def check(no_of_days, row_num, b):
  
    # to use the globally declared lists and strings
    global staff_mails
    global l2
    global l3
  
    for student in range(0, len(row_num)):
        # if total no.of.leaves equals threshold
        if no_of_days[student] is 2:
            if b is 1:
                  
                # mail_id appending
                l1.append(sheet.cell(row=row_num[student], column=2).value)
                mailstu(l1, m1)  # sending mail
            elif b is 2:
                l1.append(sheet.cell(row=row_num[student], column=2).value)
                mailstu(l1, m2)
            else:
                l1.append(sheet.cell(row=row_num[student], column=2).value)
                mailstu(l1, m3)
  
        # if total.no.of.leaves > threshold
        elif no_of_days[student] > 2:
            if b is 1:
  
                # adding roll no
                l2 = l2+str(sheet.cell(row=row_num[student], column=1).value)
  
                # student mail_id appending
                l3.append(sheet.cell(row=row_num[student], column=2).value)
                subject = "CI"  # subject based on the code number
  
            elif b is 2:
                l2 = l2+str(sheet.cell(row=row_num[student], column=1).value)
                l3.append(sheet.cell(row=row_num[student], column=2).value)
                subject = "Python"
  
            else:
                l2 = l2+str(sheet.cell(row=row_num[student], column=1).value)
                l3.append(sheet.cell(row=row_num[student], column=2).value)
                subject = "Data mining"
  
        # If threshold crossed, modify the message
        if l2 != "" and len(l3) != 0:
  
            # message for student
            msg1 = "you have lack of attendance in " + subject + " !!!"
  
            # message for staff
            msg2 = "the following students have lack of attendance in your subject : "+l2
  
            mailstu(l3, msg1)  # mail to students
            staff_id = staff_mails[b-1]  # pick respective staff's mail_id
            mailstaff(staff_id, msg2)  # mail to staff
  
# for students
def mailstu(li, msg):
    from_id = 'crazygirlaks@gmail.com'
    pwd = 'ERAkshaya485'
    s = smtplib.SMTP('smtp.gmail.com', 587, timeout=120)
    s.starttls()
    s.login(from_id, pwd)
  
    # for each student to warn send mail
    for i in range(0, len(li)):
        to_id = li[i]
        message = MIMEMultipart()
        message['Subject'] = 'Attendance report'
        message.attach(MIMEText(msg, 'plain'))
        content = message.as_string()
        s.sendmail(from_id, to_id, content)
        s.quit()
    print("mail sent to students")
  
# for staff
def mailstaff(mail_id, msg):
    from_id = 'crazygirlaks@gmail.com'
    pwd = 'ERAkshaya485'
    to_id = mail_id
    message = MIMEMultipart()
    message['Subject'] = 'Lack of attendance report'
    message.attach(MIMEText(msg, 'plain'))
    s = smtplib.SMTP('smtp.gmail.com', 587, timeout=120)
    s.starttls()
    s.login(from_id, pwd)
    content = message.as_string()
    s.sendmail(from_id, to_id, content)
    s.quit()
    print('Mail Sent to staff')
  
  
while resp is 1:
    print("1--->CI\n2--->python\n3--->DM")
  
    # enter the correspondingnumber
    y = int(input("enter subject :"))
  
    # no.of.absentees for that subject
    no_of_absentees = int(input('no.of.absentees :'))
  
    if(no_of_absentees > 1):
        x = list(map(int, (input('roll nos :').split(' '))))
    else:
        x = [int(input('roll no :'))]
  
    # list to hold row of the student in Excel sheet
    row_num = []
  
    # list to hold total no.of leaves
    # taken by ith student
    no_of_days = []
  
    for student in x:
  
        for i in range(2, r+1):
  
            if y is 1:
                if sheet.cell(row=i, column=1).value is student:
                    m = sheet.cell(row=i, column=3).value
                    m = m+1
                    sheet.cell(row=i, column=3).value = m
                    savefile()
                    no_of_days.append(m)
                    row_num.append(i)
  
            elif y is 2:
                if sheet.cell(row=i, column=1).value is student:
                    m = sheet.cell(row=i, column=4).value
                    m = m+1
                    sheet.cell(row=i, column=4).value = m+1
                    no_of_days.append(m)
                    row_num.append(i)
  
            elif y is 3:
                if sheet.cell(row=i, column=1).value is student:
                    m = sheet.cell(row=i, column=5).value
                    m = m+1
                    sheet.cell(row=i, column=5).value = m+1
                    row_num.append(i)
                    no_of_days.append(m)
  
    check(no_of_days, row_num, y)
    resp = int(input('another subject ? 1---->yes 0--->no'))

Producción:

1--->CI
2--->python
3--->DM
enter subject :1
no.of.absentees :2
roll nos :1 3
saved!
saved!
another subject ? 1---->yes 0--->no 1
1--->CI
2--->python
3--->DM
enter subject :1
no.of.absentees :1
roll no :1
saved!
mail sent to students
another subject ? 1---->yes 0--->no 1
1--->CI
2--->python
3--->DM
enter subject :1
no.of.absentees :1
roll no :1
saved!
mail sent to students
Mail Sent to staff
another subject ? 1---->yes 0--->no 0

Puntos a recordar antes de ejecutar:

  • La conexión a Internet activa es obligatoria.
  • Asegúrese de que el archivo de Excel no esté abierto en una ventana, de lo contrario, al actualizar, se mostrará «Error de permiso denegado».

Publicación traducida automáticamente

Artículo escrito por erakshaya485 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *