]> code.communitydata.science - coldcallbot-discord.git/blob - flask_app/app.py
Merge remote-tracking branch 'flask_repo/main' into flask
[coldcallbot-discord.git] / flask_app / app.py
1 #!/usr/bin/env python
2
3 import pandas as pd
4 from random import choices, shuffle
5 from datetime import datetime
6 import csv
7 import os
8 from flask import Flask, render_template, request, abort
9
10 app = Flask(__name__)
11
12 @app.route("/")
13 def hello_world():
14     return "<p>Hello, Test!</p>"
15
16
17 @app.route('/response_quality', methods=['POST'])
18 def response_quality():
19     student_name = request.form['studentName']
20     button_value = request.form['buttonValue']
21     course = request.form['course']
22     print(button_value)
23
24     fn = f'../assessments/{course}/{course}.csv'
25
26     if button_value == 'absent':
27         answered = 'F'
28         button_value = ''
29     else:
30         answered = 'T'
31
32     if button_value != 'get_next':
33         write_to_file(student_name, fn,
34                 answered=answered,
35                 assessment=button_value)
36     student = coldcall_student(course)
37     print(f'Sending {student}')
38     return student
39
40 @app.route("/coldcaller/<course>", methods=['POST','GET'])
41 def coldcaller(course):
42     public = request.args.get('public')
43     print(public)
44     if request.method == "POST":
45         student = coldcall_student(course)
46         if not student:
47             abort(404)
48     else:
49         student = ''
50     return render_template('cold_caller.html', student=student, public=public)
51
52 def coldcall_student(course):
53     if course not in ["com_304","com_411","com_674", "amap"]:
54         return None
55     weight = 2
56     students = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
57     out_fn = f'../assessments/{course}/{course}.csv'
58     caller = Caller(out_fn, students, weight)
59     student = caller.get_random_student()
60     return student
61
62 @app.route("/shuffler", methods=['POST','GET']) 
63 def shuffler():
64     course = request.args.get('course')
65     try:
66         student_list = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
67     except FileNotFoundError:
68         abort(404)
69     shuffle(student_list)
70     print(student_list)
71     return render_template('shuffler.html', result=student_list)
72
73 @app.route("/make_groups", methods=['POST','GET'])
74 def make_groups():
75     course = request.args.get('course')
76     group_size = int(request.args.get('group_size'))
77     print('running')
78     try:
79         student_list = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
80     except FileNotFoundError:
81         abort(404)
82     shuffle(student_list)
83     print(student_list)
84     print(range(0,len(student_list)//group_size + 1, group_size))
85     result = []
86     j = 1
87     for i in range(0,len(student_list), group_size):
88         result.append((j, student_list[i:i+group_size]))
89         j += 1
90     return render_template('group_maker.html', result=result)
91
92
93
94 class Caller:
95
96     def __init__(self, out_fn, students, weight = 2):
97         self.weight = weight
98         self.fn = out_fn
99         self.students = students
100         self.last_chosen = None
101         self.today = datetime.now().date()
102         self.weights_dict = self.get_weights()
103
104     def get_weights(self):
105         times_called = self.get_times_called()
106         weights_dict = {}
107         for student in self.students:
108             try:
109                 curr_tc = times_called[student]
110             except KeyError:
111                 curr_tc = 0
112             student_weight = (1/self.weight) ** curr_tc
113             weights_dict[student] = student_weight
114         return weights_dict
115
116
117     def get_times_called(self):
118         try:
119             df = pd.read_csv(self.fn)
120             if len(df) > 0:
121                 self.last_chosen = df.name.iloc[-1]
122             df.date = pd.to_datetime(df.date).dt.date
123             times_called = df[(df.answered.isin(['T','TRUE']))|(df.date==self.today)].groupby('name').size()
124             self.absent_today = df.loc[(df.date==self.today) & (df.answered.isin(['F', 'FALSE'])), 'name']
125         except FileNotFoundError or IndexError:
126             times_called = pd.DataFrame()
127             self.absent_today = pd.DataFrame()
128         return times_called
129
130     def update_weight(self, student):
131         self.weights_dict[student] /= self.weight
132
133     def get_random_student(self, can_repeat=False):
134         if not can_repeat:
135             curr_weights = {k:v for k,v in self.weights_dict.items() if k != self.last_chosen}
136         else:
137             curr_weights = self.weights_dict
138         for student in set(self.absent_today):
139             if student != self.last_chosen:
140                 del curr_weights[student]
141         rand_student = choices(list(curr_weights.keys()), weights=list(curr_weights.values()), k=1)[0]
142         print(f"Weight of {rand_student}: {curr_weights[rand_student]}")
143         self.update_weight(rand_student)
144         return(rand_student)
145
146 def write_to_file(student, fn, answered, assessment):
147     if not os.path.exists(fn):
148         with open(fn, 'w') as f:
149             f.write(','.join(['name', 'date', 'answered', 'assessment']))
150             f.write('\n')
151     with open(fn, 'a') as f:
152         out_csv = csv.writer(f)
153         out_csv.writerow([student,datetime.now().date(),answered,assessment])
154
155

Community Data Science Collective || Want to submit a patch?