In my classes, I often assign students to random teams. I use a simple notebook to do this. From the roster, I prepare a list of strings of student names. I then randomize the list and partition it into groups. I render this in an HTML table to make it easy to read and project it on the screen.
This semester, I'm adding a few widgets to make it easier to use and configure quickly during class. The widget framework supplied by IPython makes it straightforward to create lightweight applications.
I make a class with a HTML representation method that allows it to be displayed by IPython's display functions. I also make a small function to randomize a list of strings representing student names.
To make the application, I set up widgets for the sizes of the teams and whether or not to shuffle the list. I have a function that outputs random groups of teams based on the list of students, the size of teams, and whether or not to shuffle the list. Finally, a button executes this function when pressed and creates a new table of teams.
class ListTable(list):
""" Overridden list class which takes a 2-dimensional list of
the form [[1,2,3],[4,5,6]], and renders an HTML Table in
IPython Notebook. """
def _repr_html_(self):
html = ["<table>"]
for i, row in enumerate(self, start=1):
html.append("<tr>")
# create row index
html.append("<td>{0}</td>".format(i))
# add elements in row
for col in row:
html.append("<td>{0}</td>".format(col))
# close row
html.append("</tr>")
html.append("</table>")
return ''.join(html)
def group_students(students, groupsize, randomize=True):
''' Shuffle a list of strings and partition into groups.
Returns a 2-d list of strings.'''
templist = [s for s in students]
if randomize:
import random
random.shuffle(templist)
table = []
for i in range(0, len(templist), groupsize):
table.append(templist[i:i+groupsize])
return table
students = [
'Amory Lovins',
'Art Rosenfeld',
'Daniel Yergin',
'Ernest Moniz',
'Gavin Schmidt',
'Henry Ford',
'James Watt',
'Judith Curry',
'Michael Mann',
'Stephen Schneider',
'Svante Arrhenius',
'Vaclav Smil',
]
import ipywidgets
from IPython.display import display, clear_output
# set up widgets
button = ipywidgets.Button(description="Create Teams")
team_size = ipywidgets.IntSlider(min=2, max=5, value=3,
description="Team Size")
randomize = ipywidgets.Checkbox(value=True,
description='Randomize')
# define function called on button click
def on_button_clicked(b):
clear_output()
display(ListTable(group_students(students,
team_size.value,
randomize=randomize.value)))
# render and run widgets
display(randomize)
display(team_size)
display(button)
button.on_click(on_button_clicked)
Unfortunately, the widgets don't render in this static blog post, but there is a slider for the size of the teams and a button to create a new random draw.
I have a link to an app using the Binder service where you can run this.