teacher-tea 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ali Haider
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: teacher-tea
3
+ Version: 0.1.0
4
+ Summary: Help students compare teachers and build clash-free class schedules.
5
+ Author-email: Ali Haider <AliHaider7108@users.noreply.github.com>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # TeacherTea
16
+
17
+ TeacherTea is a small Python library that helps university students pick teachers and plan a weekly timetable. It includes teacher review summaries and simple schedule tools.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install teacher-tea
23
+ ```
24
+
25
+ ## Quick example
26
+
27
+ ```python
28
+ from teacher_tea import get_teacher_summary, compare_teachers, best_teacher_for
29
+ from teacher_tea import check_clash, build_timetable, free_slots, workload_estimator
30
+
31
+ print(get_teacher_summary("Jawairia Rasheed"))
32
+ print(compare_teachers("Jawairia Rasheed", "Noreen Ashraf"))
33
+ print(best_teacher_for("CS101"))
34
+
35
+ courses = [
36
+ {"course": "CS101", "teacher": "Jawairia Rasheed", "slot": ("Mon", 9.0, 10.5)},
37
+ {"course": "SE201", "teacher": "Noreen Ashraf", "slot": ("Mon", 10.0, 11.5)},
38
+ ]
39
+ print(build_timetable(courses))
40
+ print(free_slots([("Mon", 9.0, 10.5), ("Mon", 14.0, 15.5)], "Mon"))
41
+ print(workload_estimator(3, "medium"))
42
+ ```
@@ -0,0 +1,28 @@
1
+ # TeacherTea
2
+
3
+ TeacherTea is a small Python library that helps university students pick teachers and plan a weekly timetable. It includes teacher review summaries and simple schedule tools.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install teacher-tea
9
+ ```
10
+
11
+ ## Quick example
12
+
13
+ ```python
14
+ from teacher_tea import get_teacher_summary, compare_teachers, best_teacher_for
15
+ from teacher_tea import check_clash, build_timetable, free_slots, workload_estimator
16
+
17
+ print(get_teacher_summary("Jawairia Rasheed"))
18
+ print(compare_teachers("Jawairia Rasheed", "Noreen Ashraf"))
19
+ print(best_teacher_for("CS101"))
20
+
21
+ courses = [
22
+ {"course": "CS101", "teacher": "Jawairia Rasheed", "slot": ("Mon", 9.0, 10.5)},
23
+ {"course": "SE201", "teacher": "Noreen Ashraf", "slot": ("Mon", 10.0, 11.5)},
24
+ ]
25
+ print(build_timetable(courses))
26
+ print(free_slots([("Mon", 9.0, 10.5), ("Mon", 14.0, 15.5)], "Mon"))
27
+ print(workload_estimator(3, "medium"))
28
+ ```
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "teacher-tea"
7
+ version = "0.1.0"
8
+ description = "Help students compare teachers and build clash-free class schedules."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Ali Haider", email = "AliHaider7108@users.noreply.github.com"},
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+
21
+ [tool.setuptools.packages.find]
22
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,36 @@
1
+ """TeacherTea helps students pick teachers and build schedules."""
2
+
3
+ from teacher_tea.teacher_insights import (
4
+ add_review,
5
+ best_teacher_for,
6
+ compare_teachers,
7
+ get_teacher_summary,
8
+ )
9
+ from teacher_tea.schedule_helper import (
10
+ build_best_schedule,
11
+ build_timetable,
12
+ check_clash,
13
+ compare_schedules,
14
+ free_slots,
15
+ schedule_summary,
16
+ score_slot,
17
+ workload_estimator,
18
+ )
19
+
20
+ __version__ = "0.1.0"
21
+
22
+ __all__ = [
23
+ "add_review",
24
+ "get_teacher_summary",
25
+ "compare_teachers",
26
+ "best_teacher_for",
27
+ "check_clash",
28
+ "build_timetable",
29
+ "free_slots",
30
+ "workload_estimator",
31
+ "score_slot",
32
+ "build_best_schedule",
33
+ "schedule_summary",
34
+ "compare_schedules",
35
+ "__version__",
36
+ ]
@@ -0,0 +1,176 @@
1
+ """Basic timetable utilities for building a clash-free schedule."""
2
+
3
+
4
+ def _clash(slot1, slot2):
5
+ """Return True if two slots are on the same day and overlap."""
6
+ day1, start1, end1 = slot1
7
+ day2, start2, end2 = slot2
8
+
9
+ if day1 != day2:
10
+ return False
11
+
12
+ return start1 < end2 and start2 < end1
13
+
14
+
15
+ def check_clash(slot1, slot2):
16
+ """Return True if two class slots overlap on the same day."""
17
+ return _clash(slot1, slot2)
18
+
19
+
20
+ def score_slot(slot, preference):
21
+ """Return a score showing how well a slot matches a time preference."""
22
+ day, start_hour, end_hour = slot
23
+
24
+ if preference not in ("morning", "evening", "balanced"):
25
+ preference = "balanced"
26
+
27
+ if preference == "morning":
28
+ return max(0, 12 - start_hour)
29
+ if preference == "evening":
30
+ return start_hour
31
+ return 1
32
+
33
+
34
+ def build_best_schedule(courses, preference="balanced"):
35
+ """Pick the best non-clashing section for each course."""
36
+ schedule = []
37
+ unscheduled = []
38
+ chosen_slots = []
39
+
40
+ for course_info in courses:
41
+ course_name = course_info["course"]
42
+ options = sorted(
43
+ course_info["options"],
44
+ key=lambda option: score_slot(option["slot"], preference),
45
+ reverse=True,
46
+ )
47
+
48
+ picked = None
49
+ for option in options:
50
+ slot = option["slot"]
51
+ clashes = False
52
+ for chosen in chosen_slots:
53
+ if _clash(slot, chosen):
54
+ clashes = True
55
+ break
56
+ if not clashes:
57
+ picked = option
58
+ break
59
+
60
+ if picked is None:
61
+ unscheduled.append(course_name)
62
+ else:
63
+ schedule.append({
64
+ "course": course_name,
65
+ "teacher": picked["teacher"],
66
+ "slot": picked["slot"],
67
+ })
68
+ chosen_slots.append(picked["slot"])
69
+
70
+ return {"schedule": schedule, "unscheduled": unscheduled}
71
+
72
+
73
+ def schedule_summary(schedule):
74
+ """Count morning, afternoon, and evening classes in a schedule."""
75
+ morning = 0
76
+ afternoon = 0
77
+ evening = 0
78
+ days = []
79
+
80
+ for item in schedule:
81
+ day, start_hour, end_hour = item["slot"]
82
+ if day not in days:
83
+ days.append(day)
84
+
85
+ if start_hour < 12:
86
+ morning += 1
87
+ elif start_hour < 17:
88
+ afternoon += 1
89
+ else:
90
+ evening += 1
91
+
92
+ return {
93
+ "morning_classes": morning,
94
+ "afternoon_classes": afternoon,
95
+ "evening_classes": evening,
96
+ "days_on_campus": days,
97
+ }
98
+
99
+
100
+ def compare_schedules(schedule_a, schedule_b, preference):
101
+ """Compare two schedules and say which fits the preference better."""
102
+ if len(schedule_a) == 0:
103
+ avg_a = 0
104
+ else:
105
+ total_a = sum(score_slot(item["slot"], preference) for item in schedule_a)
106
+ avg_a = total_a / len(schedule_a)
107
+
108
+ if len(schedule_b) == 0:
109
+ avg_b = 0
110
+ else:
111
+ total_b = sum(score_slot(item["slot"], preference) for item in schedule_b)
112
+ avg_b = total_b / len(schedule_b)
113
+
114
+ if avg_a >= avg_b:
115
+ better = "schedule_a"
116
+ else:
117
+ better = "schedule_b"
118
+
119
+ return {
120
+ "schedule_a_avg_score": round(avg_a, 1),
121
+ "schedule_b_avg_score": round(avg_b, 1),
122
+ "better_fit": better,
123
+ }
124
+
125
+
126
+ def build_timetable(courses):
127
+ """Split courses into a clash-free schedule and a list of clashes."""
128
+ schedule = []
129
+ clashes = []
130
+
131
+ for i, course_a in enumerate(courses):
132
+ added = True
133
+ for course_b in schedule:
134
+ if check_clash(course_a["slot"], course_b["slot"]):
135
+ pair = (course_a["course"], course_b["course"])
136
+ if pair not in clashes and (pair[1], pair[0]) not in clashes:
137
+ clashes.append(pair)
138
+ added = False
139
+ break
140
+ if added:
141
+ schedule.append(course_a)
142
+
143
+ return {"schedule": schedule, "clashes": clashes}
144
+
145
+
146
+ def free_slots(busy_slots, day, day_start=8.0, day_end=17.0):
147
+ """Return free time gaps on one day between day_start and day_end."""
148
+ day_busy = []
149
+ for slot in busy_slots:
150
+ slot_day, start, end = slot
151
+ if slot_day == day:
152
+ day_busy.append((start, end))
153
+
154
+ day_busy.sort(key=lambda item: item[0])
155
+
156
+ free = []
157
+ current = day_start
158
+
159
+ for start, end in day_busy:
160
+ if start > current:
161
+ free.append((current, start))
162
+ if end > current:
163
+ current = end
164
+
165
+ if current < day_end:
166
+ free.append((current, day_end))
167
+
168
+ return free
169
+
170
+
171
+ def workload_estimator(credit_hours, difficulty="medium"):
172
+ """Estimate weekly self-study hours from credit hours and difficulty."""
173
+ multipliers = {"easy": 1.5, "medium": 2, "hard": 3}
174
+ if difficulty not in multipliers:
175
+ difficulty = "medium"
176
+ return credit_hours * multipliers[difficulty]
@@ -0,0 +1,417 @@
1
+ """Collect and summarize teacher reviews for course registration."""
2
+
3
+ _reviews = {}
4
+
5
+
6
+ def _seed_reviews():
7
+ """Load starting review data for all teachers from the faculty list."""
8
+ entries = [
9
+ ("Abdul Basit", "CS101", 4, 1, 5),
10
+ ("Abdul Jamil", "CS102", 3, 5, 5),
11
+ ("Abdullah Hasan", "SE201", 3, 3, 3),
12
+ ("Abdullah Miraj", "AI301", 5, 4, 5),
13
+ ("Abeera Ashraf", "IT205", 1, 5, 2),
14
+ ("Abu Huraira", "MATH101", 2, 4, 1),
15
+ ("Adeel Ashraf", "ENG102", 2, 3, 5),
16
+ ("Adnan Sadiq", "CS101", 1, 1, 4),
17
+ ("Afnan Iftikhar", "CS102", 5, 3, 4),
18
+ ("Ahmad Abduhu", "SE201", 1, 5, 4),
19
+ ("Ahmad Dawood", "AI301", 3, 4, 1),
20
+ ("Ahmad Hussain", "IT205", 2, 1, 5),
21
+ ("Ahmad Shaoor", "MATH101", 1, 4, 5),
22
+ ("Ahmad Sohail Aslam", "ENG102", 3, 2, 1),
23
+ ("Ahmad Yar", "CS101", 3, 4, 4),
24
+ ("Ahmed Raza", "CS102", 2, 2, 2),
25
+ ("Ahtsham Ali", "SE201", 4, 2, 2),
26
+ ("Aima Arif", "AI301", 3, 5, 1),
27
+ ("Ali Harris", "IT205", 3, 4, 2),
28
+ ("Ali Raza", "MATH101", 2, 2, 5),
29
+ ("Amal Akbar", "ENG102", 3, 1, 4),
30
+ ("Amiq Inayat", "CS101", 1, 4, 5),
31
+ ("Amjad Ali", "CS102", 5, 5, 3),
32
+ ("Ammar Haider", "SE201", 1, 4, 2),
33
+ ("Ammar Yasir Sajjad", "AI301", 1, 2, 1),
34
+ ("Ammerha Naz", "IT205", 4, 4, 3),
35
+ ("Amna Faisal", "MATH101", 3, 3, 3),
36
+ ("Anam Umera", "ENG102", 5, 3, 4),
37
+ ("Anum Saleem", "CS101", 1, 4, 3),
38
+ ("Aqsa Afzal", "CS102", 3, 5, 4),
39
+ ("Arifah Azhar", "SE201", 1, 1, 5),
40
+ ("Arman Sohail Saeed", "AI301", 5, 5, 4),
41
+ ("Arshi Iftikhar", "IT205", 1, 3, 3),
42
+ ("Arslan Ahmad", "MATH101", 4, 4, 4),
43
+ ("Arslan Anjum", "ENG102", 1, 1, 3),
44
+ ("Ashraf Ali", "CS101", 4, 2, 5),
45
+ ("Asim Aziz Waqas", "CS102", 5, 1, 4),
46
+ ("Asma", "SE201", 4, 4, 5),
47
+ ("Asma Arshad", "AI301", 1, 1, 3),
48
+ ("Asma Hamayoun", "IT205", 3, 5, 3),
49
+ ("Ateeqa Naseer", "MATH101", 3, 1, 4),
50
+ ("Awais Amin", "ENG102", 1, 2, 3),
51
+ ("Ayesha Arooj", "CS101", 2, 4, 4),
52
+ ("Ayesha Ashraf", "CS102", 5, 1, 3),
53
+ ("Ayesha Asmat", "SE201", 2, 2, 2),
54
+ ("Ayesha Ayub", "AI301", 4, 3, 1),
55
+ ("Ayesha Yasin", "IT205", 4, 5, 3),
56
+ ("Basit Sattar", "MATH101", 3, 3, 3),
57
+ ("Bilal Arif", "ENG102", 1, 5, 5),
58
+ ("Bilal Hussain", "CS101", 5, 3, 1),
59
+ ("Daniyal Adeeb", "CS102", 5, 4, 5),
60
+ ("Dr Aaqif Afzaal Abbasi", "SE201", 1, 2, 2),
61
+ ("Dr Abdul Hameed", "AI301", 5, 1, 3),
62
+ ("Dr Amber Sultan", "IT205", 4, 5, 5),
63
+ ("Dr Amjad Hussain Zahid", "MATH101", 2, 3, 4),
64
+ ("Dr Anwar Ur Rehman", "ENG102", 3, 4, 5),
65
+ ("Dr Arfan Arshad", "CS101", 2, 5, 2),
66
+ ("Dr Ashfaq Ahmad", "CS102", 1, 1, 3),
67
+ ("Dr Atif Alvi", "SE201", 3, 2, 2),
68
+ ("Dr Bilal Ashfaq Ahmed", "AI301", 5, 2, 2),
69
+ ("Dr Ehtesham Ul Haq Dar", "IT205", 2, 5, 2),
70
+ ("Dr Fawad Ali Khan", "MATH101", 5, 1, 3),
71
+ ("Dr Ghulam Mustafa", "ENG102", 3, 1, 5),
72
+ ("Dr Ifra Afzal", "CS101", 5, 3, 1),
73
+ ("Dr Iqra Javed", "CS102", 3, 1, 3),
74
+ ("Dr Irshad Ahmed", "SE201", 4, 2, 2),
75
+ ("Dr Jameel Ahmad", "AI301", 2, 5, 1),
76
+ ("Dr Kashif Ishaq", "IT205", 2, 4, 4),
77
+ ("Dr Kashif Zafar", "MATH101", 3, 4, 5),
78
+ ("Dr Malik Tahir Hassan", "ENG102", 5, 5, 5),
79
+ ("Dr Muhammad Adnan", "CS101", 5, 3, 5),
80
+ ("Dr Muhammad Ahsan", "CS102", 2, 2, 3),
81
+ ("Dr Muhammad Amir Khalil", "SE201", 3, 1, 1),
82
+ ("Dr Muhammad Asad Arshed", "AI301", 1, 1, 2),
83
+ ("Dr Muhammad Asghar Saqib", "IT205", 5, 2, 1),
84
+ ("Dr Muhammad Asim Butt", "MATH101", 2, 2, 2),
85
+ ("Dr Muhammad Azeem Javed", "ENG102", 2, 1, 5),
86
+ ("Dr Muhammad Danish Javed", "CS101", 3, 4, 5),
87
+ ("Dr Muhammad Faraz Manzoor", "CS102", 4, 4, 4),
88
+ ("Dr Muhammad Husnain Ashfaq", "SE201", 3, 4, 5),
89
+ ("Dr Muhammad Kabir", "AI301", 2, 4, 3),
90
+ ("Dr Muhammad Nadeem Ashraf", "IT205", 4, 2, 5),
91
+ ("Dr Muhammad Shoaib Farooq", "MATH101", 2, 1, 3),
92
+ ("Dr Muhammad Tahir Mushtaq", "ENG102", 3, 5, 4),
93
+ ("Dr Muhammad Tanveer", "CS101", 5, 1, 2),
94
+ ("Dr Muhammad Wasim Nawaz", "CS102", 5, 3, 3),
95
+ ("Dr Naeem Ahmed", "SE201", 1, 1, 3),
96
+ ("Dr Noman Javed", "AI301", 3, 2, 5),
97
+ ("Dr Nosheen Qamar", "IT205", 2, 1, 5),
98
+ ("Dr Raja Noshad Jamil", "MATH101", 5, 1, 2),
99
+ ("Dr Rashid Rasheed", "ENG102", 1, 2, 2),
100
+ ("Dr Rimsha Anam", "CS101", 1, 1, 4),
101
+ ("Dr Sadaf Jabeen", "CS102", 4, 1, 4),
102
+ ("Dr Saima Waseem", "SE201", 1, 3, 2),
103
+ ("Dr Sajid Mahmood", "AI301", 3, 3, 2),
104
+ ("Dr Sameera Basit", "IT205", 2, 4, 3),
105
+ ("Dr Shaista Habib", "MATH101", 2, 5, 3),
106
+ ("Dr Shariq Aziz Butt", "ENG102", 5, 3, 1),
107
+ ("Dr Shaukat Iqbal", "CS101", 2, 1, 5),
108
+ ("Dr Sohail Khalid", "CS102", 2, 1, 2),
109
+ ("Dr Syed Baqar Hussain", "SE201", 2, 1, 4),
110
+ ("Dr Syed Farooq Ali", "AI301", 3, 4, 5),
111
+ ("Dr Syed Khuram Shahzad", "IT205", 4, 5, 2),
112
+ ("Dr Tariq Mahmood", "MATH101", 3, 2, 2),
113
+ ("Dr Tayaba Anjum", "ENG102", 3, 4, 3),
114
+ ("Dr Tayyaba Anees", "CS101", 1, 3, 1),
115
+ ("Dr Toqir Ahmad Rana", "CS102", 2, 1, 3),
116
+ ("Dr Usman Inayat", "SE201", 3, 1, 3),
117
+ ("Dr Uzma Farooq", "AI301", 5, 2, 3),
118
+ ("Dr Waqar Azeem", "IT205", 5, 4, 4),
119
+ ("Dr Waseem Iqbal", "MATH101", 3, 2, 4),
120
+ ("Dr Yaser Daanial Khan", "ENG102", 5, 4, 5),
121
+ ("Emmara Zulfiqar", "CS101", 5, 5, 2),
122
+ ("Emmen Farooq", "CS102", 1, 4, 5),
123
+ ("Ezzah Aftab", "SE201", 1, 4, 2),
124
+ ("Fahad Ali", "AI301", 2, 1, 4),
125
+ ("Faheem Akbar", "IT205", 1, 4, 3),
126
+ ("Faisal Nadeem", "MATH101", 5, 1, 2),
127
+ ("Faiza Saeed", "ENG102", 2, 3, 4),
128
+ ("Faizan Younas", "CS101", 5, 2, 2),
129
+ ("Fakhar Abbas", "CS102", 4, 5, 1),
130
+ ("Fareeha Rauf", "SE201", 5, 5, 5),
131
+ ("Faria Ferooz", "AI301", 3, 3, 2),
132
+ ("Faria Nazir", "IT205", 5, 5, 1),
133
+ ("Farrukh Liaquat", "MATH101", 5, 5, 3),
134
+ ("Fasiha Ashraf", "ENG102", 3, 2, 4),
135
+ ("Fatima Shehzad", "CS101", 1, 1, 5),
136
+ ("Fatima Tariq", "CS102", 4, 3, 5),
137
+ ("Fiza Kazmi", "SE201", 5, 2, 3),
138
+ ("Furqan Rustam", "AI301", 1, 3, 3),
139
+ ("Ghulam Murtaza", "IT205", 1, 1, 5),
140
+ ("Habiba Habib", "MATH101", 4, 2, 5),
141
+ ("Hafiz Abdul Rehman", "ENG102", 1, 4, 5),
142
+ ("Hafiz Ahsan Arshad", "CS101", 1, 3, 4),
143
+ ("Hafiz Muhammad Ahmad Nawaz", "CS102", 5, 3, 2),
144
+ ("Hafiz Muhammad Ashja Khan", "SE201", 2, 5, 4),
145
+ ("Hafiz Muhammad Rizwan", "AI301", 1, 2, 3),
146
+ ("Hafiz Muhammad Tahir Sohail", "IT205", 1, 3, 4),
147
+ ("Hafiz Saifullah", "MATH101", 5, 5, 5),
148
+ ("Hafiza Daheem", "ENG102", 1, 1, 2),
149
+ ("Hafiza Hina Javed", "CS101", 3, 4, 5),
150
+ ("Hafsa Rafique", "CS102", 5, 1, 3),
151
+ ("Hafsa Riasat", "SE201", 2, 2, 3),
152
+ ("Hafsa Zafar", "AI301", 3, 4, 3),
153
+ ("Haiqa Saman", "IT205", 3, 4, 5),
154
+ ("Hajran Saleem", "MATH101", 3, 2, 2),
155
+ ("Halima Jamil", "ENG102", 4, 5, 4),
156
+ ("Hamda Raheen", "CS101", 2, 2, 4),
157
+ ("Hamid Raza Malik", "CS102", 3, 1, 2),
158
+ ("Hamza Mustafa", "SE201", 1, 2, 1),
159
+ ("Hareem Aslam", "AI301", 1, 2, 3),
160
+ ("Haseeb Imdad", "IT205", 5, 4, 2),
161
+ ("Hashir Hasnain Asghar", "MATH101", 5, 4, 4),
162
+ ("Hassaan Ahmad", "ENG102", 4, 2, 4),
163
+ ("Hassan Bashir", "CS101", 4, 4, 2),
164
+ ("Hassan Moatasam Awan", "CS102", 5, 3, 5),
165
+ ("Hina Bari", "SE201", 4, 2, 1),
166
+ ("Insha Rafique", "AI301", 5, 1, 5),
167
+ ("Iqra Khalid", "IT205", 1, 1, 3),
168
+ ("Iqra Khalil", "MATH101", 4, 4, 1),
169
+ ("Javeria Iqbal", "ENG102", 2, 4, 4),
170
+ ("Jawad Hassan", "CS101", 4, 1, 3),
171
+ ("Jawairia Rasheed", "CS102", 1, 5, 4),
172
+ ("Jaweria Aamir Ali", "SE201", 2, 2, 4),
173
+ ("Jaweria Aslam", "AI301", 1, 1, 5),
174
+ ("Kamla Salahuddin", "IT205", 2, 5, 1),
175
+ ("Kamran Arshad", "MATH101", 1, 4, 5),
176
+ ("Kawish Habiba", "ENG102", 2, 5, 4),
177
+ ("Khadija Shams", "CS101", 5, 1, 5),
178
+ ("Khaqan Zaheer", "CS102", 4, 1, 5),
179
+ ("Khawaja Ubaid Ur Rehman", "SE201", 2, 3, 1),
180
+ ("Kinza Sardar", "AI301", 2, 2, 2),
181
+ ("Komal Naseer", "IT205", 2, 4, 5),
182
+ ("Laila Zahra", "MATH101", 2, 5, 5),
183
+ ("Laraib Kanwal", "ENG102", 4, 1, 4),
184
+ ("Madiha Jalil", "CS101", 4, 3, 4),
185
+ ("Mahira Zainab", "CS102", 2, 1, 5),
186
+ ("Mahmood Hussain", "SE201", 2, 1, 4),
187
+ ("Maida Sabir", "AI301", 4, 1, 5),
188
+ ("Mariha Asad", "IT205", 4, 1, 1),
189
+ ("Mariya Tauqeer", "MATH101", 5, 2, 2),
190
+ ("Maryam Afzal", "ENG102", 3, 1, 5),
191
+ ("Mehak Saleem", "CS101", 2, 4, 1),
192
+ ("Mehr Un Nisa", "CS102", 4, 3, 4),
193
+ ("Mehwish Afshan", "SE201", 5, 2, 2),
194
+ ("Mian Ahmed Shafiq", "AI301", 5, 4, 2),
195
+ ("Mian Raybal Akhtar", "IT205", 5, 2, 5),
196
+ ("Mirza Muhammad Haris Baig", "MATH101", 1, 4, 2),
197
+ ("Mobashirah Nasir", "ENG102", 1, 1, 1),
198
+ ("Mohammad Umar Farooq", "CS101", 3, 1, 1),
199
+ ("Mudassar Hussain", "CS102", 1, 1, 2),
200
+ ("Muhammad Abdul Jabbar", "SE201", 5, 1, 4),
201
+ ("Muhammad Abdullah Fiaz", "AI301", 2, 3, 3),
202
+ ("Muhammad Ali", "IT205", 1, 5, 3),
203
+ ("Muhammad Amir Waseem", "MATH101", 1, 1, 3),
204
+ ("Muhammad Asif Subhani", "ENG102", 5, 1, 3),
205
+ ("Muhammad Awais Ali", "CS101", 3, 3, 4),
206
+ ("Muhammad Ayesh Butt", "CS102", 5, 1, 5),
207
+ ("Muhammad Bilal", "SE201", 4, 1, 5),
208
+ ("Muhammad Bilal Anwar", "AI301", 5, 5, 1),
209
+ ("Muhammad Ehsan", "IT205", 1, 5, 3),
210
+ ("Muhammad Fahad Irshad", "MATH101", 5, 1, 3),
211
+ ("Muhammad Faheem Subhnani", "ENG102", 4, 1, 2),
212
+ ("Muhammad Faran Aslam", "CS101", 5, 3, 1),
213
+ ("Muhammad Farrukh Nadeem", "CS102", 5, 5, 4),
214
+ ("Muhammad Hamza Farooq", "SE201", 2, 2, 4),
215
+ ("Muhammad Haroon", "AI301", 1, 3, 3),
216
+ ("Muhammad Ibtissam", "IT205", 3, 1, 3),
217
+ ("Muhammad Imran Shafi", "MATH101", 4, 4, 3),
218
+ ("Muhammad Jawad Akhtar", "ENG102", 4, 4, 2),
219
+ ("Muhammad Maaz Waseem", "CS101", 1, 2, 4),
220
+ ("Muhammad Masab Akram", "CS102", 3, 1, 2),
221
+ ("Muhammad Mustansar Ali Khan", "SE201", 5, 4, 5),
222
+ ("Muhammad Nabeel", "AI301", 4, 5, 3),
223
+ ("Muhammad Nadeem", "IT205", 3, 5, 3),
224
+ ("Muhammad Rehan Akhtar", "MATH101", 4, 5, 1),
225
+ ("Muhammad Rizwan", "ENG102", 1, 1, 1),
226
+ ("Muhammad Rizwan Jamil", "CS101", 4, 1, 4),
227
+ ("Muhammad Rumaan", "CS102", 2, 3, 3),
228
+ ("Muhammad Sadaqat Janjua", "SE201", 2, 5, 5),
229
+ ("Muhammad Saqib", "AI301", 3, 2, 3),
230
+ ("Muhammad Saquib Nazir", "IT205", 2, 2, 3),
231
+ ("Muhammad Sarwar", "MATH101", 5, 5, 3),
232
+ ("Muhammad Shahbaz Ali", "ENG102", 2, 3, 1),
233
+ ("Muhammad Shehan Latif", "CS101", 5, 1, 4),
234
+ ("Muhammad Sheraz Nawaz", "CS102", 1, 5, 5),
235
+ ("Muhammad Shoaib", "SE201", 2, 2, 5),
236
+ ("Muhammad Siddiqui", "AI301", 3, 5, 4),
237
+ ("Muhammad Tahir", "IT205", 3, 5, 1),
238
+ ("Muhammad Umar Farooq", "MATH101", 3, 1, 5),
239
+ ("Muhammad Waseem Asif", "ENG102", 2, 2, 4),
240
+ ("Muhammad Wisal Khan", "CS101", 5, 2, 1),
241
+ ("Muhammad Zubair Shafique", "CS102", 4, 3, 5),
242
+ ("Mutahher Mahmood", "SE201", 1, 5, 4),
243
+ ("Muzahir Saleem", "AI301", 2, 2, 3),
244
+ ("Muzzamil Mustafa", "IT205", 1, 2, 5),
245
+ ("Nabeel Ali Khan", "MATH101", 2, 5, 4),
246
+ ("Nafeesa Yousaf", "ENG102", 1, 2, 5),
247
+ ("Naila Aslam", "CS101", 4, 3, 5),
248
+ ("Naseer Ahmad", "CS102", 1, 2, 1),
249
+ ("Naveed Husain", "SE201", 3, 4, 2),
250
+ ("Nitasha Arooj", "AI301", 2, 5, 4),
251
+ ("Noaman Saleem", "IT205", 4, 5, 5),
252
+ ("Noreen Ashraf", "MATH101", 4, 4, 3),
253
+ ("Numan Babar", "ENG102", 1, 3, 3),
254
+ ("Osama Tariq", "CS101", 4, 2, 4),
255
+ ("Qamar Abbas Arbie", "CS102", 3, 3, 5),
256
+ ("Qanza Azam", "SE201", 4, 3, 4),
257
+ ("Rabia Khalid", "AI301", 3, 3, 3),
258
+ ("Rabia Qasim", "IT205", 2, 5, 4),
259
+ ("Rafia Asad Khan", "MATH101", 3, 2, 1),
260
+ ("Raja Muzammil Muneer", "ENG102", 4, 5, 3),
261
+ ("Rana Marwat Hussain", "CS101", 3, 3, 4),
262
+ ("Reamsha Khan", "CS102", 2, 2, 5),
263
+ ("Rehan Raza", "SE201", 5, 5, 5),
264
+ ("Reshmail Fatima", "AI301", 1, 3, 1),
265
+ ("Rida Ayesha", "IT205", 1, 1, 5),
266
+ ("Roma Rasheed", "MATH101", 3, 4, 4),
267
+ ("Sadia Abbas Shah", "ENG102", 4, 4, 1),
268
+ ("Sahrish Shafique", "CS101", 1, 5, 3),
269
+ ("Saima Shaheen", "CS102", 5, 2, 1),
270
+ ("Samar Ikram", "SE201", 3, 1, 5),
271
+ ("Sameer Ahmed", "AI301", 4, 2, 5),
272
+ ("Sana Akhtar Naseer", "IT205", 2, 3, 4),
273
+ ("Sana Naseem", "MATH101", 2, 3, 3),
274
+ ("Sana Zubair", "ENG102", 5, 2, 5),
275
+ ("Sania Qamar", "CS101", 1, 5, 2),
276
+ ("Sardar Waqar Khan", "CS102", 1, 2, 3),
277
+ ("Sehrish Munawar", "SE201", 2, 2, 2),
278
+ ("Sehrish Riaz", "AI301", 4, 5, 5),
279
+ ("Shafaq Khan", "IT205", 2, 5, 4),
280
+ ("Shahbaz Qadeer", "MATH101", 3, 4, 4),
281
+ ("Shaheen Bibi", "ENG102", 4, 5, 5),
282
+ ("Shahzaib Mushtaq Shah", "CS101", 4, 5, 2),
283
+ ("Shamila Ghafoor", "CS102", 4, 4, 1),
284
+ ("Shanza Zaman", "SE201", 5, 5, 2),
285
+ ("Sharmeen Amir", "AI301", 3, 3, 4),
286
+ ("Sheeza Zaheer", "IT205", 3, 2, 1),
287
+ ("Shehla Afzal", "MATH101", 5, 5, 1),
288
+ ("Sheza Shabir", "ENG102", 4, 3, 2),
289
+ ("Shinawar Naeem", "CS101", 5, 5, 5),
290
+ ("Shoaib Khan", "CS102", 1, 1, 3),
291
+ ("Sidra Ramzan", "SE201", 4, 2, 5),
292
+ ("Sowaiba Khan", "AI301", 1, 5, 4),
293
+ ("Sundas Sagheer", "IT205", 1, 4, 4),
294
+ ("Syed Hamed Raza", "MATH101", 2, 5, 5),
295
+ ("Syed Shaheer Afzal", "ENG102", 3, 3, 4),
296
+ ("Syeda Inshrah Fatima", "CS101", 5, 1, 3),
297
+ ("Syeda Nimra Zamir", "CS102", 2, 2, 1),
298
+ ("Tahir Mehmood", "SE201", 2, 2, 2),
299
+ ("Tahir Shahzad", "AI301", 1, 2, 4),
300
+ ("Taila Jabeen", "IT205", 1, 4, 2),
301
+ ("Talha Bin Sohail", "MATH101", 5, 5, 1),
302
+ ("Umair Ghazanfar", "ENG102", 1, 2, 3),
303
+ ("Umer Usman", "CS101", 3, 2, 5),
304
+ ("Usama Ahmed", "CS102", 5, 5, 2),
305
+ ("Usama Amjad", "SE201", 3, 3, 2),
306
+ ("Usama Husnain", "AI301", 5, 1, 2),
307
+ ("Usman Ali", "IT205", 3, 4, 2),
308
+ ("Usman Ul Haq", "MATH101", 2, 5, 1),
309
+ ("Uzair Arslan", "ENG102", 4, 4, 3),
310
+ ("Uzair Zia", "CS101", 1, 4, 2),
311
+ ("Waleed Riaz", "CS102", 4, 1, 2),
312
+ ("Waqar Ashiq", "SE201", 3, 2, 4),
313
+ ("Waqar Hussain", "AI301", 3, 4, 1),
314
+ ("Warda Mehboob", "IT205", 4, 1, 3),
315
+ ("Zahida Tayyab", "MATH101", 3, 4, 4),
316
+ ("Zahoor Ahmed Khan", "ENG102", 2, 5, 3),
317
+ ("Zarnab Azam", "CS101", 5, 4, 4),
318
+ ("Zaryab Qayyum", "CS102", 2, 1, 3),
319
+ ("Zeenat Tanveer", "SE201", 2, 3, 3),
320
+ ("Zeeshan Akram", "AI301", 5, 2, 2),
321
+ ("Zohaib Ashraf", "IT205", 1, 1, 4),
322
+ ("Zunaira Zulfiqar", "MATH101", 1, 2, 5),
323
+ ]
324
+ for teacher, course, attendance_strictness, teaching_quality, grading_leniency in entries:
325
+ if teacher not in _reviews:
326
+ _reviews[teacher] = {}
327
+ if course not in _reviews[teacher]:
328
+ _reviews[teacher][course] = []
329
+ _reviews[teacher][course].append({
330
+ "attendance_strictness": attendance_strictness,
331
+ "teaching_quality": teaching_quality,
332
+ "grading_leniency": grading_leniency,
333
+ })
334
+
335
+
336
+ _seed_reviews()
337
+
338
+
339
+ def add_review(teacher, course, attendance_strictness, teaching_quality, grading_leniency):
340
+ """Add a student review for a teacher and course."""
341
+ scores = {
342
+ "attendance_strictness": attendance_strictness,
343
+ "teaching_quality": teaching_quality,
344
+ "grading_leniency": grading_leniency,
345
+ }
346
+ for name, value in scores.items():
347
+ if not isinstance(value, int) or value < 1 or value > 5:
348
+ raise ValueError(f"{name} must be an integer between 1 and 5")
349
+
350
+ if teacher not in _reviews:
351
+ _reviews[teacher] = {}
352
+ if course not in _reviews[teacher]:
353
+ _reviews[teacher][course] = []
354
+
355
+ review = {
356
+ "attendance_strictness": attendance_strictness,
357
+ "teaching_quality": teaching_quality,
358
+ "grading_leniency": grading_leniency,
359
+ }
360
+ _reviews[teacher][course].append(review)
361
+ return f"Review added for {teacher} in {course}."
362
+
363
+
364
+ def get_teacher_summary(teacher):
365
+ """Return average review scores and course list for one teacher."""
366
+ if teacher not in _reviews or not _reviews[teacher]:
367
+ return f"No reviews found for {teacher}."
368
+
369
+ all_reviews = []
370
+ courses = sorted(_reviews[teacher].keys())
371
+ for course in courses:
372
+ all_reviews.extend(_reviews[teacher][course])
373
+
374
+ count = len(all_reviews)
375
+ avg_attendance = sum(r["attendance_strictness"] for r in all_reviews) / count
376
+ avg_teaching = sum(r["teaching_quality"] for r in all_reviews) / count
377
+ avg_grading = sum(r["grading_leniency"] for r in all_reviews) / count
378
+
379
+ return {
380
+ "teacher": teacher,
381
+ "review_count": count,
382
+ "avg_attendance_strictness": round(avg_attendance, 2),
383
+ "avg_teaching_quality": round(avg_teaching, 2),
384
+ "avg_grading_leniency": round(avg_grading, 2),
385
+ "courses": courses,
386
+ }
387
+
388
+
389
+ def compare_teachers(teacher1, teacher2):
390
+ """Compare review summaries for two teachers."""
391
+ return {
392
+ teacher1: get_teacher_summary(teacher1),
393
+ teacher2: get_teacher_summary(teacher2),
394
+ }
395
+
396
+
397
+ def best_teacher_for(course):
398
+ """Find the teacher with the highest teaching quality for a course."""
399
+ best_name = None
400
+ best_score = -1
401
+
402
+ for teacher, courses in _reviews.items():
403
+ if course not in courses:
404
+ continue
405
+ reviews = courses[course]
406
+ avg = sum(r["teaching_quality"] for r in reviews) / len(reviews)
407
+ if avg > best_score:
408
+ best_score = avg
409
+ best_name = teacher
410
+
411
+ if best_name is None:
412
+ return f"No reviews found for course {course}."
413
+
414
+ return {
415
+ "teacher": best_name,
416
+ "avg_teaching_quality": round(best_score, 2),
417
+ }
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: teacher-tea
3
+ Version: 0.1.0
4
+ Summary: Help students compare teachers and build clash-free class schedules.
5
+ Author-email: Ali Haider <AliHaider7108@users.noreply.github.com>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # TeacherTea
16
+
17
+ TeacherTea is a small Python library that helps university students pick teachers and plan a weekly timetable. It includes teacher review summaries and simple schedule tools.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install teacher-tea
23
+ ```
24
+
25
+ ## Quick example
26
+
27
+ ```python
28
+ from teacher_tea import get_teacher_summary, compare_teachers, best_teacher_for
29
+ from teacher_tea import check_clash, build_timetable, free_slots, workload_estimator
30
+
31
+ print(get_teacher_summary("Jawairia Rasheed"))
32
+ print(compare_teachers("Jawairia Rasheed", "Noreen Ashraf"))
33
+ print(best_teacher_for("CS101"))
34
+
35
+ courses = [
36
+ {"course": "CS101", "teacher": "Jawairia Rasheed", "slot": ("Mon", 9.0, 10.5)},
37
+ {"course": "SE201", "teacher": "Noreen Ashraf", "slot": ("Mon", 10.0, 11.5)},
38
+ ]
39
+ print(build_timetable(courses))
40
+ print(free_slots([("Mon", 9.0, 10.5), ("Mon", 14.0, 15.5)], "Mon"))
41
+ print(workload_estimator(3, "medium"))
42
+ ```
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/teacher_tea/__init__.py
5
+ src/teacher_tea/schedule_helper.py
6
+ src/teacher_tea/teacher_insights.py
7
+ src/teacher_tea.egg-info/PKG-INFO
8
+ src/teacher_tea.egg-info/SOURCES.txt
9
+ src/teacher_tea.egg-info/dependency_links.txt
10
+ src/teacher_tea.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ teacher_tea