Properly document the damn thing.

This commit is contained in:
Abdulkadir Furkan Şanlı 2019-01-11 15:06:35 +01:00
parent 42e6042405
commit 4e05e3380a
No known key found for this signature in database
GPG Key ID: B0B350A3CD74C184
3 changed files with 39 additions and 29 deletions

View File

@ -2,15 +2,15 @@
ib-clearance is a program which helps schools manage the entrance and exiting of their IB Diploma Program students. Due to the unique nature of IB students' timetables, the program helps to automatically check individual timetables and give clearance to students who have finished for the day. ib-clearance is a program which helps schools manage the entrance and exiting of their IB Diploma Program students. Due to the unique nature of IB students' timetables, the program helps to automatically check individual timetables and give clearance to students who have finished for the day.
## Building ## Building & running
The code is currently designed to run on Python 3.6.*. The code is currently designed to run on Python 3.6.* and requires the [`getch`](https://pypi.org/project/getch/) module on platforms other than Windows.
Binaries can be built using the `pyinstaller` package (`pyinstaller --onefile ib-clearance.py`). Binaries can be built using [`pyinstaller`](https://pypi.org/project/PyInstaller/): `pyinstaller --onefile ib-clearance.py`
## Database specification ## Database specification
The program requires a SQLite database `database.db` in the working directory, containing data for all classes. The program requires a SQLite database `database.db` in the working directory, containing data for all school classes.
`database.db` must contain: `database.db` must contain:

View File

@ -6,6 +6,7 @@ To-Do List
- [x] Make database contain data for all classes - [x] Make database contain data for all classes
- [x] Flexible mandatory subjects - [x] Flexible mandatory subjects
- [x] Make script functional (sorta) - [x] Make script functional (sorta)
- [x] Document the damn thing
## v0.3 ## v0.3
- [ ] Usability and GUI - [ ] Usability and GUI

View File

@ -14,12 +14,11 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sqlite3 import sqlite3
import time import time
from os import name from os import name
# Import getch from msvcrt if running on Windows. # Windows has standard library getch, use that.
if name == "nt": if name == "nt":
from msvcrt import getch from msvcrt import getch
else: else:
@ -27,18 +26,23 @@ else:
def connect_database(file): def connect_database(file):
""" """Get database connection object.
Creates and returns Connection object.
:param file: database file Connect to SQLite database and return a connection object.
:param file: SQLite database
""" """
conn = sqlite3.connect(file) conn = sqlite3.connect(file)
return conn return conn
def get_data(conn): def get_data(conn):
""" """Get student data.
Requests student ID and returns integer tuple (id, class) with valid
student id, corresponding class no. (1 or 2) and extra subject IDs. Request student ID. Return integer tuple (id, class, other) with
valid student ID, corresponding class number and "other" subject
IDs.
:param conn: Connection object :param conn: Connection object
""" """
try: try:
@ -46,12 +50,10 @@ def get_data(conn):
cur = conn.cursor() cur = conn.cursor()
cur.execute("SELECT id, student_class, other FROM students") cur.execute("SELECT id, student_class, other FROM students")
ids = cur.fetchall() ids = cur.fetchall() # ids is list of tuples.
for tup in ids: for tup in ids:
# ids is list of tuples
if id == tup[0]: if id == tup[0]:
# return tuple x with valid id, class and extra class IDs
lis = list(tup) lis = list(tup)
lis[2] = lis[2].split() lis[2] = lis[2].split()
return lis return lis
@ -63,13 +65,17 @@ def get_data(conn):
def select_final_time(conn, day, stuple): def select_final_time(conn, day, stuple):
""" """Select student finishing time.
Returns ending time of final lesson student must attend, or None.
Returns ending time (type struct_time) of final lesson student must
attend on given day, or None if no lessons.
:param conn: Connection object :param conn: Connection object
:param day: current weekday, lowercase str :param day: current weekday, lowercase str
:param stuple: tuple with student ID no. and class no., int :param stuple: student data tuple returned by get_data
""" """
cur = conn.cursor() cur = conn.cursor()
# Select finishing time of IB lessons.
cur.execute(""" cur.execute("""
SELECT end_time SELECT end_time
FROM timetable FROM timetable
@ -84,13 +90,14 @@ def select_final_time(conn, day, stuple):
AND lesson_class = ? AND lesson_class = ?
ORDER BY end_time DESC ORDER BY end_time DESC
LIMIT 1 LIMIT 1
""", (stuple[0], day, stuple[1])) """, (stuple[0], day, stuple[1])) # Queries return None if no matches.
ib_finish = cur.fetchone() ib_finish = cur.fetchone()
if ib_finish is not None: if ib_finish is not None:
ib_finish = parse_time_string(ib_finish[0]) ib_finish = parse_time_string(ib_finish[0])
# Select finishing time of other lessons.
others = [] others = []
for sub in stuple[2]: for subject in stuple[2]:
cur.execute(""" cur.execute("""
SELECT end_time SELECT end_time
FROM timetable FROM timetable
@ -100,10 +107,10 @@ def select_final_time(conn, day, stuple):
AND lesson_class = ? AND lesson_class = ?
ORDER BY end_time DESC ORDER BY end_time DESC
LIMIT 1 LIMIT 1
""", (sub, stuple[0], day, stuple[1])) """, (subject, stuple[0], day, stuple[1]))
other_finish = cur.fetchone() subject_finish = cur.fetchone()
if other_finish is not None: if subject_finish is not None:
others.append(parse_time_string(other_finish[0])) others.append(parse_time_string(subject_finish[0]))
if not others: if not others:
others_finish = None others_finish = None
else: else:
@ -125,8 +132,11 @@ def select_final_time(conn, day, stuple):
def parse_time_string(timestring): def parse_time_string(timestring):
""" """Convert time string to tuple.
Parses given 24h time string of format "HH:MM" into struct_time.
Parses given 24h time string of format "HH:MM" into the struct_time
object provided by library time.
:param timestring: time string "HH:MM" :param timestring: time string "HH:MM"
""" """
structtime = time.strptime(timestring, "%H:%M") structtime = time.strptime(timestring, "%H:%M")
@ -141,7 +151,7 @@ def main():
while True: while True:
student_data = get_data(conn) student_data = get_data(conn)
day = time.strftime("%A").lower() day = time.strftime("%A").lower() # db days are also lowercase.
finish_time = select_final_time(conn, day, student_data) finish_time = select_final_time(conn, day, student_data)
current_time = parse_time_string(time.strftime("%H:%M")) current_time = parse_time_string(time.strftime("%H:%M"))
@ -154,13 +164,12 @@ def main():
print("\nPress X key to exit, other key to run again.") print("\nPress X key to exit, other key to run again.")
key = getch() key = getch()
# msvcrt.getch returns type bytes, decode into str.
if isinstance(key, bytes): if isinstance(key, bytes):
# msvcrt.getch returns type bytes, decode into str.
key = key.decode() key = key.decode()
if key.upper() == "X": if key.upper() == "X":
break break
# Run main() if script is run standalone.
if __name__ == "__main__": if __name__ == "__main__":
main() main()