In late August 2019, the seminar organizing committee (reachable at colloquium@lists.roe.ac.uk) designed and administered a survey to obtain feedback on the efficacy of the seminar series design.
This notebook analyzes the results. If you would like to perform your own analysis, please email the seminar organizing committee or Michael Petersen (michael.petersen@roe.ac.uk) for assistance.
We have omitted the demographic responses. We are confident that the reponses constitute a representative sample of ROE members. Additionally, no cross-tabs are reported in this analysis (i.e. no separation along demographic lines). An internal analysis did not indicate any significant results as a function of different demographic elements. Following standard practice, categories with fewer than five responses are noted, rather than reporting the results. The note should not be interpreted as though no reponses for the selections were recorded.
We received 49 total responses.
# standard python modules
import numpy as np
# enable markdown printing
from IPython.display import Markdown, display
def printmd(string):
"""wrap markdown printing"""
display(Markdown(string))
# how-to
#printmd('**bold**')
#printmd('_italics_')
# plotting utilities
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
# adjust rcparams to MSP style
mpl.rcParams['xtick.labelsize'] = 10
mpl.rcParams['ytick.labelsize'] = 10
mpl.rcParams['font.weight'] = 'medium'
mpl.rcParams['axes.linewidth'] = 1.5
mpl.rcParams['xtick.major.width'] = 1.5
mpl.rcParams['xtick.minor.width'] = 0.75
mpl.rcParams['xtick.minor.visible'] = True
mpl.rcParams['ytick.major.width'] = 1.5
mpl.rcParams['ytick.minor.width'] = 0.75
mpl.rcParams['ytick.minor.visible'] = True
# definition to read questions from the google forms format
def summarize_answer(question,\
multiple=True,\
delimiter=b'., ',\
criteria=0,\
significance=5):
"""summarize an answer to a question
inputs
----------
question : (list) Responses to a question in list format.
multiple : (boolean) True if the question allowed multiple responses
delimiter : (string) Safeguard to delimit the google forms format
criteria : (boolean evaluation) Allow for cross-tab analysis
significance : (integer) How many responses must be recorded for reporting
returns
----------
none -- printed results only.
"""
if criteria!=0:
question = question[criteria]
if multiple:
#answerlist = np.array([np.array(q.split(b',')) for q in question)
flatanswers = np.array([])
for x in np.array([np.array(q.split(delimiter)) for q in question]):
flatanswers = np.concatenate([flatanswers,x])
else:
flatanswers = question
flatanswers = np.array([q.strip(b'.').strip(b'') for q in flatanswers])
#print(flatanswers)
answers = np.unique(flatanswers[flatanswers!=b''])
nanswers = np.zeros(answers.size)
for ans in flatanswers:
nanswers[ans==answers] += 1
#print(answers,nanswers)
for ans in (-1.*nanswers).argsort():
if nanswers[ans] < significance:
continue
try:
printmd('**'+str(int(nanswers[ans]))+'** - {0}'.format(\
answers[ans].decode().lstrip()\
))
except:
printmd('**'+str(int(nanswers[ans]))+'** - {0}'.format(\
answers[ans]\
))
Read the file format from Google Forms, and organize into a keyed dictionary.
keys = ["time","tenure","position","affiliation","gender","events",\
"events_reason","dinner_reason","meeting_reason",\
"host_reason","temperature","importance","alternate_seminar",\
"format_change","lunch_idea","postgrad_format","format_comment",\
"time_option","lecture_rank","higgs_rank","stobie_rank","emails",\
"location_comment","pre_options_food","pre_options_drink","post_options",\
"food_suggestions","general_comments",\
"coffee_temperature","coffee_number","coffee_speakers","coffee_attendance",\
"coffee_announcements","coffee_time","coffee_format","coffee_policy",\
"coffee_timing","coffee_comments"]
# read in the survey responses
Stats = np.genfromtxt('ROE-ColloquiumResponses-3',\
dtype={'names': list(keys),\
'formats': ('S200','S200','S200','S200','S200','S200','S200','S200','S200','S200','i4','S400','S200','S200','S200','S200','S400','S200','S200','S200','S200','S200','S200','S200','S200','S200','S200','S400','i4','S200','S200','S200','S200','S200','S200','S200','S200','S200')},
delimiter='\t',skip_header=1)
# Read in the question prompts specifically
f= open('ROE-ColloquiumResponses-3'); a = f.readline()
# reorganize into a dictionary
QDict = {}
for ikey,key in enumerate(keys):
QDict[key] = a.split('\t')[ikey]
fig = plt.figure(figsize=(6,4))
ax1 = fig.add_axes([0.15,0.45,0.8,0.48])
temprange = np.arange(1,12,1)
tempval = np.zeros(temprange.size)
for x in Stats['temperature']:
if x > 0:
tempval[x-1] += 1
ax1.plot(temprange,tempval,color='black',drawstyle='steps-mid')#,linestyle='dashed')
#dates = np.array([x.decode().strip() for x in Stats['date']])
ax1.set_ylabel('# of responses',size=12)
ax1.set_xlabel('score',size=12)
ax1.set_title('N='+str(int(Stats['temperature'].size)),size=12)
printmd('_'+QDict['temperature']+'_')
ax1.tick_params(axis="y",which='both',direction="in"); ax1.tick_params(axis="x",which='both',direction="in",pad=5); ax1.yaxis.set_ticks_position('both'); ax1.xaxis.set_ticks_position('both')
If you are only concerned that we are shortchanging the food options, here are the results:
# talking about food...
# which questions?
foodkeys = ["pre_options_food","pre_options_drink","post_options"]
for qq in foodkeys:
printmd('_'+QDict[qq]+'_')
summarize_answer(Stats[qq],delimiter=b', ')
print('')
# programatic questions
# which questions?
programkeys = ["events","events_reason","dinner_reason","meeting_reason",\
"host_reason","importance","alternate_seminar",\
"format_change","lunch_idea","postgrad_format",\
"time_option","emails"]
for qq in programkeys:
printmd('_'+QDict[qq]+'_')
summarize_answer(Stats[qq])
print('')