18
0

added flask app from jeremy

This commit is contained in:
2024-09-28 12:32:19 -07:00
parent 92e65de771
commit e756c448c0
7 changed files with 336 additions and 0 deletions

144
flask_app/app.py Normal file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env python
import pandas as pd
from random import choices, shuffle
from datetime import datetime
import csv
import os
from flask import Flask, render_template, request, abort
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, Test!</p>"
@app.route('/response_quality', methods=['POST'])
def response_quality():
student_name = request.form['studentName']
button_value = request.form['buttonValue']
course = request.form['course']
fn = f'../assessments/{course}/{course}.csv'
if button_value == 'absent':
answered = 'F'
button_value = ''
else:
answered = 'T'
write_to_file(student_name, fn,
answered=answered,
assessment=button_value)
return 'Received feedback from ' + student_name + ': ' + button_value
@app.route("/coldcaller/<course>", methods=['POST','GET'])
def coldcaller(course):
if course not in ["com_304","com_411","com_674"]:
abort(404)
weight = 2
students = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
student = ''
out_fn = f'../assessments/{course}/{course}.csv'
caller = Caller(out_fn, students, weight)
if request.method == "POST":
student = caller.get_random_student()
return render_template('cold_caller.html', student=student)
@app.route("/shuffler", methods=['POST','GET'])
def shuffler():
course = request.args.get('course')
try:
student_list = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
except FileNotFoundError:
abort(404)
shuffle(student_list)
print(student_list)
return render_template('shuffler.html', result=student_list)
@app.route("/make_groups", methods=['POST','GET'])
def make_groups():
course = request.args.get('course')
group_size = int(request.args.get('group_size'))
print('running')
try:
student_list = pd.read_csv(f'../assessments/{course}/{course}_students.csv').Name
except FileNotFoundError:
abort(404)
shuffle(student_list)
print(student_list)
print(range(0,len(student_list)//group_size + 1, group_size))
result = []
j = 1
for i in range(0,len(student_list), group_size):
result.append((j, student_list[i:i+group_size]))
j += 1
return render_template('group_maker.html', result=result)
class Caller:
def __init__(self, out_fn, students, weight = 2):
self.weight = weight
self.fn = out_fn
self.students = students
self.last_chosen = None
self.today = datetime.now().date()
self.weights_dict = self.get_weights()
def get_weights(self):
times_called = self.get_times_called()
weights_dict = {}
for student in self.students:
try:
curr_tc = times_called[student]
except KeyError:
curr_tc = 0
student_weight = (1/self.weight) ** curr_tc
weights_dict[student] = student_weight
return weights_dict
def get_times_called(self):
try:
df = pd.read_csv(self.fn)
if len(df) > 0:
self.last_chosen = df.name.iloc[-1]
df.date = pd.to_datetime(df.date).dt.date
times_called = df[(df.answered.isin(['T','TRUE']))|(df.date==self.today)].groupby('name').size()
self.absent_today = df.loc[(df.date==self.today) & (df.answered.isin(['F', 'FALSE'])), 'name']
except FileNotFoundError or IndexError:
times_called = pd.DataFrame()
return times_called
def update_weight(self, student):
self.weights_dict[student] /= self.weight
def get_random_student(self, can_repeat=False):
if not can_repeat:
curr_weights = {k:v for k,v in self.weights_dict.items() if k != self.last_chosen}
else:
curr_weights = self.weights_dict
for student in set(self.absent_today):
print(curr_weights.keys())
print(student in curr_weights)
if student != self.last_chosen:
del curr_weights[student]
rand_student = choices(list(curr_weights.keys()), weights=list(curr_weights.values()), k=1)[0]
print(f"Weight of {rand_student}: {curr_weights[rand_student]}")
self.update_weight(rand_student)
return(rand_student)
def write_to_file(student, fn, answered, assessment):
if not os.path.exists(fn):
with open(fn, 'w') as f:
f.write(','.join(['name', 'date', 'answered', 'assessment']))
f.write('\n')
with open(fn, 'a') as f:
out_csv = csv.writer(f)
out_csv.writerow([student,datetime.now().date(),answered,assessment])

25
flask_app/static/main.css Normal file
View File

@@ -0,0 +1,25 @@
body {
background: Linen;
margin-top: 50px;
margin-left: 100px;
margin-right: 100px;
font-family: Georgia, serif;
color: DarkSlateGray;
font-size: 1.3em;
}
p {
font-family: Georgia, serif;
font-size: 1em;
color: DarkSlateGray;
}
h1 {
font-family: Verdana, Geneva, sans-serif;
font-size: 2.5em;
color: FireBrick;
}
.rand-button {
font-size: .8em;
}

View File

@@ -0,0 +1,23 @@
$(document).ready(function() {
$('#goodButton, #badButton, #neutralButton, #absentButton').on('click', function() {
var studentName = $('#studentName').text();
console.log(studentName);
var buttonValue = $(this).val();
var courseCode = window.location.pathname.split('/').pop();
$.ajax({
url: '/response_quality',
type: 'POST',
data: {
studentName: studentName,
buttonValue: buttonValue,
course: courseCode
},
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
});

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>Random Student Picker</title>
<link rel="stylesheet" href='/static/main.css' />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="{{ url_for('static', filename='process_button.js') }}"></script>
</head>
<body>
<h3>
The next student is:
</h3>
<h2 id='studentName' name='studentName'>{{student}}</h2>
<form method="post" id="todo-form">
<button class='rand-button' type="submit">Get random student</button>
</form>
<button class='assessment' id="goodButton" value="G">Good</button>
<button class='assessment' id="badButton" value="B">Bad</button>
<button class='assessment' id="neutralButton" value="M">Neutral</button>
<button class='assessment' id="absentButton" value="absent">Absent</button>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>Random Student Picker</title>
<link rel="stylesheet" href='/static/main.css' />
</head>
<body>
<h3>
Groups:
</h3>
{% for group in result %}
<h2>Group {{group[0]}}</h2>
<ul>
{% for member in group[1] %}
<li> {{member}} </li>
{% endfor %}
</ul>
{% endfor %}
</body>
</html>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>Shuffled List</title>
<link rel="stylesheet" href='/static/main.css' />
</head>
<body>
<h3>
Shuffled List:
</h3>
<ul>
{% for member in result %}
<li> {{member}} </li>
{% endfor %}
</ul>
</body>
</html>

71
flask_app/test.csv Normal file
View File

@@ -0,0 +1,71 @@
name,date,answered,assessment
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
owen,2022-01-01,,
dad,2022-01-01,,
dad,2022-01-01,,
1 name date answered assessment
2 owen 2022-01-01
3 dad 2022-01-01
4 owen 2022-01-01
5 owen 2022-01-01
6 dad 2022-01-01
7 owen 2022-01-01
8 dad 2022-01-01
9 dad 2022-01-01
10 dad 2022-01-01
11 owen 2022-01-01
12 owen 2022-01-01
13 dad 2022-01-01
14 dad 2022-01-01
15 dad 2022-01-01
16 dad 2022-01-01
17 owen 2022-01-01
18 owen 2022-01-01
19 owen 2022-01-01
20 owen 2022-01-01
21 owen 2022-01-01
22 dad 2022-01-01
23 dad 2022-01-01
24 dad 2022-01-01
25 dad 2022-01-01
26 owen 2022-01-01
27 owen 2022-01-01
28 dad 2022-01-01
29 owen 2022-01-01
30 dad 2022-01-01
31 dad 2022-01-01
32 owen 2022-01-01
33 owen 2022-01-01
34 dad 2022-01-01
35 dad 2022-01-01
36 owen 2022-01-01
37 owen 2022-01-01
38 dad 2022-01-01
39 owen 2022-01-01
40 owen 2022-01-01
41 dad 2022-01-01
42 owen 2022-01-01
43 dad 2022-01-01
44 owen 2022-01-01
45 dad 2022-01-01
46 owen 2022-01-01
47 owen 2022-01-01
48 dad 2022-01-01
49 dad 2022-01-01
50 dad 2022-01-01
51 owen 2022-01-01
52 dad 2022-01-01
53 dad 2022-01-01
54 owen 2022-01-01
55 owen 2022-01-01
56 dad 2022-01-01
57 owen 2022-01-01
58 owen 2022-01-01
59 dad 2022-01-01
60 dad 2022-01-01
61 dad 2022-01-01
62 dad 2022-01-01
63 owen 2022-01-01
64 owen 2022-01-01
65 owen 2022-01-01
66 owen 2022-01-01
67 dad 2022-01-01
68 dad 2022-01-01
69 owen 2022-01-01
70 dad 2022-01-01
71 dad 2022-01-01