# StuSys by Johnny Devine, October 2018
#
# This program is to be executed by python3 on a raspberry pi with a ten key attached
#
#
# This program requires one additional file to opperate: studentlist.csv
# This file can be created by copy-and-pasting the standard TAC rosters from eSchool+ into and excel
# spreadsheet, then saving it as "CSV (Comma delimindate)(*.csv)" type file.
# Remove empty rows and any headers that included in the copy-paste process.
#
# The program below assumes the studentlist.csv file has the following format:
# "last_name, first_name",ID_number,grade_level,gender,birthday
# Only the first two values (name and ID number) are used in this program.
#
# Save that file as "studentlist.csv" or change the name in the path_to_student_lists variable below.
# This file can be moved to the pi using WinSCP, or a similar network protocol, or via a USB.
#
# As the code is written, stusys.py and studentlist.csv are in a created directory (/home/pi/stysys)
# If you put them somewhere else, don't forget to update the pathway to studentlist.csv in the
# variables below.
#
# It is ciritcal that the time and date be correctly set on the raspberry pi. This will happen automatically
# if the pi is connected to the internet.
# If the pi is not connected to the internet, it can be set from the command line using a command like:
# sudo date -s "Thu Aug 9 21:31:26 UTC 2012"
# More info about the command above can be found by entering the command "man date"
# If the time and date is set on a non-internet connected pi, this information will be lost if the pi
# is disconnected from a power source.
#include relevent libraries:
#import RPi.GPIO as GPIO
import math, time, os, csv, random, datetime
#initialize GPIO pins, if used later for indicator lights
#GPIO.setmode(GPIO.BOARD)
#GPIO.setwarnings(False)
#GPIO.cleanup()
#define constants and initialize variables
shutdown_code = "8675309"
time_set_code = "8463"
disco_code = "42"
# Student list was created in Excel with exported data from school grade book
# It has columns for name (last,first), student ID number, grade, gender, birthday.
path_to_student_list = "/home/pi/stusys/studentlist.csv"
# Student event file has columns for student_name, student_id, CHECKOUT_COUNT, CHECKOUT_DURATION, CHECKOUT_BATHROOM, CHECKOUT_DRINK, CHECKOUT_OFFICE, CHECKOUT_OTHER, TARDY_COUNT, TARDY_DURATION, TARDY_BUS, TARDY_OVERSLEPT, TARDY_TEACHER, TARDY_MEDICAL, TARDY_BATHROOM, TARDY_LOSTTRACK, TARDY_OTHER
path_to_studentevents = "/home/pi/stusys/studentevents.csv"
student_row = 0
student_name = ""
student_id = ""
student_grade = ""
student_gender = ""
student_birthday = ""
pass_to_main_menu = False
student_event_headers = ["student name", "student ID", "timestamp", "checked out", "duration of check out", "checked out to go to bathroom", "checked out to get a drink of water", "checked out to go to the office or another room", "checked out for some other reason", "were tardy", "length of the tardy", "tardy because of bus trouble", "tardy because you overslept", "tardy because another staff member kept you", "tardy because of a medical reason", "tardy becuase you were in the bathroom", "tardy because you lost track of time", "tardy because of some other reason"]
CHECKOUT_COUNT = 0
CHECKOUT_DURATION = 0
CHECKOUT_BATHROOM = 0
CHECKOUT_DRINK = 0
CHECKOUT_OFFICE = 0
CHECKOUT_OTHER = 0
TARDY_COUNT = 0
TARDY_DURATION = 0
TARDY_BUS = 0
TARDY_OVERSLEPT = 0
TARDY_TEACHER = 0
TARDY_MEDICAL = 0
TARDY_BATHROOM = 0
TARDY_LOSTTRACK = 0
TARDY_OTHER = 0
#Bell schedule.
#[starting_hour, starting_minute, ending_hour, ending_minute]
first_period = [8,15,9,45]
second_period = [9,55,11,25]
mentor_period = [11,55,12,15]
third_period = [12,20,13,50]
fourth_period = [14,0,15,30]
friday_mentor = [10,30,12,30]
friday_AA = [13,30,15,30]
normal_schedule = [first_period, second_period, mentor_period, third_period, fourth_period]
friday_schedule = [friday_mentor, friday_AA]
# above here is the definition and initialization
# of variables and constants
###################################################################################
###################################################################################
# below here is the definition of functions
# that are used in the main code
def IdentifyStudent(id):
global pass_to_main_menu, student_row, student_name, student_id, student_grade, student_gender, student_birthday
with open(path_to_student_list) as csvfile:
readcsv = csv.reader(csvfile,delimiter=',')
names = []
id_numbers = []
grades = []
genders = []
birthdays = []
for row in readcsv:
name = row[0]
id_number = row[1]
grade = row[2]
gender = row[3]
birthday = row[4]
names.append(name)
id_numbers.append(id_number)
grades.append(grade)
birthdays.append(birthday)
escape = False
pass_to_main_menu = False
while escape == False:
if id == "0":
escape = True
pass_to_main_menu = True
elif id not in id_numbers or id == "":
print("\033c")
print("ID number was not found")
id = input("Please enter your ID number, or enter '0' to return to main menu: ")
else:
escape = True
reference_index = id_numbers.index(id)
student_row = reference_index
student_name = names[reference_index]
student_id = id_numbers[reference_index]
student_grade = grades[reference_index]
student_gender = grades[reference_index]
student_birthday = birthdays[reference_index]
def AddStudentEvent():
global student_name, student_id, CHECKOUT_COUNT, CHECKOUT_DURATION, CHECKOUT_BATHROOM, CHECKOUT_DRINK, CHECKOUT_OFFICE, CHECKOUT_OTHER, TARDY_COUNT, TARDY_DURATION, TARDY_BUS, TARDY_OVERSLEPT, TARDY_TEACHER, TARDY_MEDICAL, TARDY_BATHROOM, TARDY_LOSTTRACK, TARDY_OTHER
data_to_write = [student_name, student_id, datetime.datetime.now(), CHECKOUT_COUNT, CHECKOUT_DURATION, CHECKOUT_BATHROOM, CHECKOUT_DRINK, CHECKOUT_OFFICE, CHECKOUT_OTHER, TARDY_COUNT, TARDY_DURATION, TARDY_BUS, TARDY_OVERSLEPT, TARDY_TEACHER, TARDY_MEDICAL, TARDY_BATHROOM, TARDY_LOSTTRACK, TARDY_OTHER]
with open(path_to_studentevents, 'a') as eventfile:
eventwriter = csv.writer(eventfile)
eventwriter.writerow(data_to_write)
for i in range(3, len(data_to_write)):
data_to_write[i] = 0
def DataSummary(summary_choice):
global student_event_headers, student_name, student_id, CHECKOUT_COUNT, CHECKOUT_DURATION, CHECKOUT_BATHROOM, CHECKOUT_DRINK, CHECKOUT_OFFICE, CHECKOUT_OTHER, TARDY_COUNT, TARDY_DURATION, TARDY_BUS, TARDY_OVERSLEPT, TARDY_TEACHER, TARDY_MEDICAL, TARDY_BATHROOM, TARDY_LOSTTRACK, TARDY_OTHER
print("\033c")
with open(path_to_studentevents) as csvfile:
readcsv = csv.reader(csvfile,delimiter=',')
names = []
id_numbers = []
timestamps = []
checkout_counts = []
checkout_durations = []
checkout_bathrooms = []
checkout_drinks = []
checkout_offices = []
checkout_others = []
tardy_counts = []
tardy_durations = []
tardy_busses = []
tardy_overslepts = []
tardy_teachers = []
tardy_medicals = []
tardy_bathrooms = []
tardy_losttracks = []
tardy_others = []
for row in readcsv:
name = row[0]
id_number = row[1]
timestamp = row[2]
checkout_count = row[3]
checkout_duration = row[4]
checkout_bathroom = row[5]
checkout_drink = row[6]
checkout_office = row[7]
checkout_other = row[8]
tardy_count = row[9]
tardy_duration = row[10]
tardy_bus = row[11]
tardy_overslept = row[12]
tardy_teacher = row[13]
tardy_medical = row[14]
tardy_bathroom = row[15]
tardy_losttrack = row[16]
tardy_other = row[17]
names.append(name)
id_numbers.append(id_number)
timestamps.append(timestamp)
checkout_counts.append(checkout_count)
checkout_durations.append(checkout_duration)
checkout_bathrooms.append(checkout_bathroom)
checkout_drinks.append(checkout_drink)
checkout_offices.append(checkout_office)
checkout_others.append(checkout_other)
tardy_counts.append(tardy_count)
tardy_durations.append(tardy_duration)
tardy_busses.append(tardy_bus)
tardy_overslepts.append(tardy_overslept)
tardy_teachers.append(tardy_teacher)
tardy_medicals.append(tardy_medical)
tardy_bathrooms.append(tardy_bathroom)
tardy_losttracks.append(tardy_losttrack)
tardy_others.append(tardy_other)
total_checkout_count = 0
total_checkout_duration = 0
total_checkout_bathroom = 0
total_checkout_drink = 0
total_checkout_office = 0
total_checkout_other = 0
total_tardy_count = 0
total_tardy_duration = 0
total_tardy_bus = 0
total_tardy_overslept = 0
total_tardy_teacher = 0
total_tardy_medical = 0
total_tardy_bathroom = 0
total_tardy_losttrack = 0
total_tardy_other = 0
row = 0
for i in names:
if i == student_name:
total_checkout_count = total_checkout_count + int(checkout_counts[row])
total_checkout_duration = total_checkout_duration + int(checkout_durations[row])
total_checkout_bathroom = total_checkout_bathroom + int(checkout_bathrooms[row])
total_checkout_drink = total_checkout_drink + int(checkout_drinks[row])
total_checkout_office = total_checkout_office + int(checkout_offices[row])
total_checkout_other = total_checkout_other + int(checkout_others[row])
total_tardy_count = total_tardy_count + int(tardy_counts[row])
total_tardy_duration = total_tardy_duration + int(tardy_durations[row])
total_tardy_bus = total_tardy_bus + int(tardy_busses[row])
total_tardy_overslept = total_tardy_overslept + int(tardy_overslepts[row])
total_tardy_teacher = total_tardy_teacher + int(tardy_teachers[row])
total_tardy_medical = total_tardy_medical + int(tardy_medicals[row])
total_tardy_bathroom = total_tardy_bathroom + int(tardy_bathrooms[row])
total_tardy_losttrack = total_tardy_losttrack + int(tardy_losttracks[row])
total_tardy_other = total_tardy_other + int(tardy_others[row])
row = row + 1
if summary_choice == 1:
m, s = divmod(total_checkout_duration, 60)
print("Check-out summary for: " + student_name)
print("\nYou've checked out " + str(total_checkout_count) + " times, missing \na total of " + str(m) + " minutes and " + str(s) + " seconds of class.")
print("\nThe reasons were:\n")
print(" Went to the bathroom: " + str(total_checkout_bathroom) + " times.")
print(" Went for a drink: " + str(total_checkout_drink) + " times.")
print(" Went to the office: " + str(total_checkout_office) + " times.")
print(" Other reasons: " + str(total_checkout_other) + " times.")
elif summary_choice == 2:
print("Tardy summary for: " + student_name)
print("\nYou've been trady " + str(total_tardy_count) + " times, missing \na total of " + str(total_tardy_duration) + " minutes of class.")
print("\nThe reasons you were late are:\n")
print(" Bus trouble: " + str(total_tardy_bathroom) + " times.")
print(" Overslept: " + str(total_tardy_overslept) + " times.")
print(" Kept by teacher: " + str(total_tardy_teacher) + " times.")
print(" Medical issue: " + str(total_tardy_medical) + " times.")
print(" In the bathroom: " + str(total_tardy_bathroom) + " times.")
print(" Lost track of time: " + str(total_tardy_losttrack) + " times.")
print(" Other reasons: " + str(total_tardy_other) + " times.")
else:
print("Summary of last two events for: " + student_name + "\n\n")
student_event_lists = [names, id_numbers, timestamps, checkout_counts, checkout_durations, checkout_bathrooms, checkout_drinks, checkout_offices, checkout_others, tardy_counts, tardy_durations, tardy_busses, tardy_overslepts, tardy_teachers, tardy_medicals, tardy_bathrooms, tardy_losttracks, tardy_others]
number_of_summaries = 0
record_row = len(names) - 1
for entry in reversed(names):
if entry == student_name and number_of_summaries < 2:
reconstructed_event = []
event_item = 3
for list in student_event_lists[3:]:
if list[record_row] != "0":
current_list = student_event_lists[event_item]
reconstructed_event.append(current_list[record_row])
reconstructed_event.append(student_event_headers[event_item])
event_item += 1
print(timestamps[record_row])
print("You were " + reconstructed_event[5] + " for " + reconstructed_event[2] + " minute(s).\n\n")
number_of_summaries += 1
record_row -= 1
input("\nPress enter to continue...")
# above here is the definition of functions
# called in the main code
###########################################################################################
###########################################################################################
# below here is the main 'try/except' portion
# of the code
try:
#main body of program remains in this while loop
while True:
print("\033c")
print("Welcome to StuSys: The Student Managment System!\n")
print("1: I need to check out \n2: I was tardy \n3: View my data summary \n4: Check the time \n\n")
initial_input = input("\nPlease enter your selection: ")
#SHUTDOWN
if initial_input == shutdown_code:
os.system("sudo shutdown -h now")
#DISCO MODE - does nothing currently
elif initial_input == disco_code:
print("disc mode")
input()
os.system("sudo python3 discomode.py")
#SET TIME - does nothing currently
elif initial_input == time_set_code:
print("set time")
input()
#GUMBALL QUEST - does nothing currently
elif initial_input == "5":
print("gumball quest is not ready yet...")
input()
#CHECK TIME
elif initial_input == "4":
print("\033c")
current_time = datetime.datetime.now()
print("StuSys thinks the current date and time is:\n\n" + str(current_time))
print("(year-month-day hour:minutes:seconds)\n\n")
print("If this is wrong, please notify the teacher.")
input("\n\nPress enter to return to the main menu...")
#DATA SUMMARY
elif initial_input == "3":
print("\033c")
id_number_input = input("Please enter ID number, or enter 0 to return to main menu\n: ")
IdentifyStudent(id_number_input)
if pass_to_main_menu == False:
summary_escape = False
while summary_escape == False:
print("\033c")
summary_choice = input("What summary do you want?\n\n1) Check-out summary\n2) Tardy summary\n3) Summary of last two events\n\nEnter '0' to return to the main menu.\n\n: ")
if summary_choice == "0":
summary_escape = True
elif summary_choice not in ["1", "2", "3"]:
print("Sorry, that is an invalid choice. Please try again.")
time.sleep(1)
elif summary_choice in ["1", "2", "3"]:
summary_escape = True
DataSummary(int(summary_choice))
#TARDY
elif initial_input == "2":
print("\033c")
id_number_input = input("Please enter ID number, or enter 0 to return to main menu: ")
IdentifyStudent(id_number_input)
if pass_to_main_menu == False:
print("\033c\n")
tardy_escape = False
while tardy_escape == False:
print("Welcome " + student_name + "!")
tardy_choice = input("Please enter the option that best describes why you're tardy: \n\n 1: Bus trouble\n 2: Overslept\n 3: With another staff member\n 4: Medical issue\n 5: In the bathroom\n 6: Lost track of time\n 7: Other (explain to teacher after you're done here)\n\nEnter '0' to return to main menu\n: ")
if tardy_choice == "0":
tardy_escape = True
elif tardy_choice not in ["1", "2", "3", "4", "5", "6", "7"]:
print("\033c")
print("Sorry, that was an invalid choice. Try again.")
elif tardy_choice == "1":
TARDY_BUS = 1
tardy_choice = "of bus trouble."
tardy_escape = True
elif tardy_choice == "2":
TARDY_OVERSLEPT = 1
tardy_choice = "you overslept."
tardy_escape = True
elif tardy_choice == "3":
TARDY_TEACHER = 1
tardy_choice = "you were with another staff member."
tardy_escape = True
elif tardy_choice == "4":
TARDY_MEDICAL = 1
tardy_choice = "of a medical issue."
tardy_escape = True
elif tardy_choice == "5":
TARDY_BATHROOM = 1
tardy_choice = "you were in the bathroom."
tardy_escape = True
elif tardy_choice == "6":
TARDY_LOSTTRACK = 1
tardy_choice = "you lost track of time."
tardy_escape = True
elif tardy_choice == "7":
TARDY_OTHER = 1
tardy_choice = "of some other reason (please explain to the teacher)."
tardy_escape = True
if tardy_escape != False:
print("\033c")
day_of_week = datetime.datetime.today().weekday()
now = datetime.datetime.now()
if day_of_week in [5,6]:
print("It's a weekend. No one is tardy today!")
input()
elif day_of_week == 4:
during_class_time = False
for period in friday_schedule:
if int(now.hour) >= period[0] and int(now.hour) <= period[2]:
during_class_time = True
hours_late = int(now.hour) - period[0]
if hours_late > 0:
print("if loop")
minutes_late = 60 - period[1] + int(now.minute)
else:
minutes_late = int(now.minute) - period[1]
print("\033c")
TARDY_DURATION = minutes_late
input("You are " + str(TARDY_DURATION) + " minutes late because " + tardy_choice + "\n\nThis time and reason have been added to your record.\n\nPress enter to return to the main menu...")
if during_class_time == False:
print("\033c")
tardy_escape = True
input("There is no class happening right now.\n\nYou need to log your tardiness as soon as you arrive. \n\nSpeak to the teacher during passing period if you are concerned about your attendance mark.\n\nPress enter to return to the main menu...")
else:
during_class_time = False
for period in normal_schedule:
if int(now.hour) >= period[0] and int(now.hour) <= period[2]:
during_class_time = True
hours_late = int(now.hour) - period[0]
if hours_late > 0:
print("if loop")
minutes_late = 60 - period[1] + int(now.minute)
else:
minutes_late = int(now.minute) - period[1]
print("\033c")
TARDY_DURATION = minutes_late
input("You are " + str(TARDY_DURATION) + " minutes late because " + tardy_choice + "\n\nThis time and reason have been added to your record.\n\nPress enter to return to the main menu...")
if during_class_time == False:
print("\033c")
tardy_escape = True
input("There is no class happening right now.\n\nYou need to log your tardiness as soon as you arrive. \n\nSpeak to the teacher during passing period if you are concerned about your attendance mark.\n\nPress enter to return to the main menu...")
if tardy_escape != False:
TARDY_COUNT = 1
AddStudentEvent()
#CHECKOUT
elif initial_input == "1":
print("\033c")
id_number_input = input("Please enter ID number, or enter 0 to return to main menu: ")
IdentifyStudent(id_number_input)
if pass_to_main_menu == False:
print("\033c\n")
checkout_escape = False
while checkout_escape == False:
print("Welcome " + student_name + "!")
checkout_choice = input("Please enter the number of the option that best describes your reason for checking out: \n\n1: Bathroom\n2: Drinking Fountain\n3: Office or Another Teacher\n4: Other\n\nEnter '0' to return to main menu\n: ")
if checkout_choice == "0":
checkout_escape = True
elif checkout_choice not in ["1", "2", "3", "4"]:
print("\033c")
print("Sorry, that was an invalid choice. Try again.")
elif checkout_choice == "1":
CHECKOUT_BATHROOM = 1
checkout_choice = "they went to the restroom."
checkout_escape = True
elif checkout_choice == "2":
checkout_choice = "they are getting a drink of water."
CHECKOUT_DRINK = 1
checkout_escape = True
elif checkout_choice == "3":
checkout_choice = "they went to the office or another room."
CHECKOUT_OFFICE = 1
checkout_escape = True
elif checkout_choice == "4":
checkout_choice = "of some other reason."
CHECKOUT_OTHER = 1
checkout_escape = True
CHECKOUT_COUNT = 1
print("\033c")
checkout_start = time.time()
id_correct = False
while id_correct == False and checkout_choice != "0":
print(student_name + " has left the room because " + checkout_choice + "\n\nNo one else can leave the room until they return.\n\n")
unlock_id = input(student_name + ": when you return, please enter your ID: ")
if unlock_id == "1234567" or unlock_id == student_id:
id_correct = True
print("\033c")
checkout_end = time.time()
CHECKOUT_DURATION = int(checkout_end - checkout_start)
print("You were gone for " + str(CHECKOUT_DURATION) + " seconds.\nThis time has been added to your semester total.")
print("\nRestarting system now...")
CHECKOUT_DURATION = math.ceil(CHECKOUT_DURATION/60)
AddStudentEvent()
time.sleep(3)
else:
print("Sorry, that is not the ID for " + student_name)
time.sleep(1)
print("\033c")
#INVALID INPUT
else:
print("Sorry, invalid input. Try again.")
time.sleep(1)
#If an error occurs or control-C is used, the GPIO pins should still be cleaned up
except:
print("exception raised")
KeyboardInterrupt
# GPIO.cleanup()