#Attendance class will do the following: #->Check whether there is a class (from Google/any other calendar) #->Mark a particular student present #->Persist attendance records to db (current strategy is to serialise/pickle a 2D list and store it as a blob in the db) #->Display attendance records for a particular module #->Display the attendance record for a particular student #The nipo calendar is here(https://calendar.google.com/calendar/b/1?cid=ODBmc2g3ajllMjg5amYybGJuYThmODk2dDBAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ). It is a Google calendar where when you invite it to any events it is ging to accept given that this event doesnt clash with anything else on its calendar. This will be the default calendar that'll be used for timetabling in this project. from nipo import get_logger, test_session from nipo.db.schema import Student, Course, Module from datetime import datetime import pandas as pd import pickle logger = get_logger("nipo_attendance") # This class (MarkAttendance) will have functions related to marking attendance. The core function of this class will be to take as input a student id, a module and a date. The class would then mark that student present for that class. The intended strategy to use is to have a multidimensional Python list (to mimic a matrix or excel sheet) where the columns are all the class dates and the rows are the student attendances. Each cell (intersection between row r and column c) is then a binary value representing whether the student r attended the class on the date c. # This class should also be able to serialise and deserialise this list in order to persist it in the DB as a blob. # As an aside, the reason why the attendance record is kept as a list and not its own table in the db is for flexibility. We are assuming that we dont know all the dates for all the classes in the future. Some classes may be cancelled and others moved. If the attendance was a table in the DB, it would be very cumbersome, dangerous and complicated to continually edit the table's schema. As a list, it is trivial to add a new "column". In effect we have traded speed for flexibility. # In future, maybe consider moving to a non relational DB #Ignore this class for now. I see no use for it. Currently use ModuleAttendance and StudentAttendance. It may be useful in some way in future though class MarkAttendance: def __init__(self, studentid, modulecode, moduledate): '''Create a single attendance record for a student in a module''' pass
from nipo.tests.populate import populate_testdb from nipo.db.schema import Base import configparser import os setup( name="nipo", version="0.6.1", author="Mcflyhalf", author_email="*****@*****.**", description=("An implementation of classroom attendance monitoring"), keywords="facial recognition classroom attendance", packages=find_packages(), ) logger = get_logger("nipo_setup") logger.info("Nipo python package successfuly installed") class NipoConfig: #Create tables (DB needs to have been created in advance outside of python) def __init__(self, engine): self.newconfig(engine) def create_tables(self, engine): tables = Base.metadata.sorted_tables #Create (but not populate all tables in the db schema) logger.info("Attempting to create tables") #Do stuff here using metadata from the classes in the schema
#This file will eventually be removed. It is here to test functionality that interfaces with objects that havent been created or functionality that requires a populated DB (for this we use nipo_test which is a mirror of nipo but whose contents are used for testing purposes) #Documentation for creating an instance of the mapped classes is very well done at https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#create-an-instance-of-the-mapped-class from nipo import test_session, get_logger from nipo.db.schema import Module, Student, Course, Venue, User, PrivilegeLevel from nipo.attendance import ModuleAttendance, get_student_attendance from datetime import datetime import random logger = get_logger("nipo_populate") session = test_session session_engine = session.get_bind() conn_details = session_engine.url sd = [datetime(2029,4,30,10,30)] sd.append(datetime(2029,5,7,10,30)) sd.append(datetime(2029,5,8,10,30)) sd.append(datetime(2029,5,9,10,30)) sd.append(datetime(2029,5,10,10,30)) sd.append(datetime(2029,5,11,10,30)) def populate_testdb(): '''Populate the test db with test info''' logger.info("Populating DB >>{}<< with dummy data for integration testing".format(conn_details)) venue1 = Venue(code = "H7009", name = "Hall 7 Rm 9", capacity = 20) venue2 = Venue(code = "EMB101", name = "Eng MAin Building 101" , capacity = 30) venue3 = Venue(code = "4A", name = "Form 4A", capacity = 60) venue4 = Venue(code = "SHAC", name = "Shirrin Aumreedy-Cziffra" , capacity = 35 ) venue5 = Venue(code = "PLMM", name = "Patrice Lumumba" , capacity = 40) venues = [venue1, venue2, venue3, venue4, venue5]