<jupyter_start><jupyter_text>Getting and wrangling LIFE data from Google Firebase<jupyter_code>import re
import json
import pyrebase
import warnings
import numpy as np
import pandas as pd
from datetime import datetime
from datetime import timedelta

from PIL import Image
from io import BytesIO

import seaborn as sns
import chart_studio.plotly as py
import chart_studio.tools as tls
import plotly.graph_objs as go
import matplotlib.pyplot as plt
import plotly.figure_factory as ff
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

%matplotlib inline
warnings.filterwarnings('ignore')
init_notebook_mode(True)

sns.set(rc={'figure.figsize':(9,6),'lines.linewidth': 5, 'lines.markersize': 10})
plt.style.use('seaborn-whitegrid')
sns.set_context("notebook", font_scale=1.2)
sns.set_style("whitegrid",{"font.family": ["Corbel"]})
ROOT_DATA ='D:/Statistical Programming Projects/Experiment/'
config={}
with open("firebaseConfig.txt","r") as configFile:
    for line in configFile.readlines():
        key,value = line.strip().split("=")
        config.update({key:value.strip()})
firebase = pyrebase.initialize_app(config)
auth = firebase.auth()
user = auth.sign_in_with_email_and_password('<EMAIL>','<PASSWORD>')
db = firebase.database()<jupyter_output><empty_output><jupyter_text>Get study demographic info for participants<jupyter_code>neonate_demo = db.child("resus").child("extras").get()
users_sessionless = pd.DataFrame()
user_session_mix_sessionless = pd.DataFrame()
user_session_mix_session = pd.DataFrame()
user_session_perfect = pd.DataFrame()

def check_is_date(item):
    session = None
    try:
        session = datetime.strptime(item, '%b %d, %Y, %I:%M:%S %p')
    except ValueError:
        try:
            session = datetime.strptime(item, '%d %b %Y %H:%M:%S')
        except ValueError:
            session=item
    isdate=isinstance(session,datetime)
    return(isdate)

def return_as_date(item):
    session = None
    try:
        session = datetime.strptime(item, '%b %d, %Y, %I:%M:%S %p')
    except ValueError:
        try:
            session = datetime.strptime(item, '%d %b %Y %H:%M:%S')
        except ValueError:
            print(str(item)+" is not a date value")
    return(session)
            

for learner_node in neonate_demo.each():
    user_id = learner_node.key() 
    user_session_node = learner_node.val()
    under_session=True    
    key_count = len(list(set(user_session_node.keys())))
    keys = list(set(user_session_node.keys()))    
    key_has_dates = [check_is_date(key) for key in keys]
    if any(key_has_dates):
        if all(key_has_dates):
            for key,value in user_session_node.items():
                session = datetime.strptime(key, '%b %d, %Y, %I:%M:%S %p')
                value['Session']=session
                user_details_session = pd.DataFrame(value, index=[user_id])
                user_session_perfect = pd.concat([user_session_perfect,user_details_session])
        else:
            user_vals_mixed_sessionless = {}
            for key,value in user_session_node.items():
                if not check_is_date(key):
                    user_vals_mixed_sessionless[str(key)] = value
                else:
                    session = return_as_date(key)
                    value['Session']=session
                    user_details_mixed_session = pd.DataFrame(value, index=[user_id])
                    user_session_mix_session = pd.concat([user_session_mix_session,user_details_mixed_session])
                    
            user_details_mixed_sessionless = pd.DataFrame(user_vals_mixed_sessionless, index=[user_id])
            user_session_mix_sessionless = pd.concat([user_session_mix_sessionless,user_details_mixed_sessionless])
                    
    else:
        user_vals_sessionless = {}
        for key,value in user_session_node.items():
            user_vals_sessionless[str(key)] = value
        user_details_sessionless = pd.DataFrame(user_vals_sessionless, index=[user_id])
        users_sessionless = pd.concat([users_sessionless,user_details_sessionless])
        
users_sessionless.reset_index(inplace=True)
users_sessionless.rename(columns={'index':'User'},inplace=True)
user_session_perfect.reset_index(inplace=True)
user_session_perfect.rename(columns={'index':'User'},inplace=True)
user_session_mix_sessionless.reset_index(inplace=True)
user_session_mix_sessionless.rename(columns={'index':'User'},inplace=True)
user_session_mix_session.reset_index(inplace=True)
user_session_mix_session.rename(columns={'index':'User'},inplace=True)


all_users = pd.concat([users_sessionless,user_session_perfect,user_session_mix_sessionless,user_session_mix_session])


users_exclude = all_users.User[(all_users.Email.isin(all_users.Email.dropna().unique()))&(all_users.Email.str.contains('@cloudtestlab'))].tolist()

tester_keys=[          
             '<KEY>',
             '0061B8E8C32D352CC3EAFFFC2C93C6F8',
             '<KEY>',
             '30E967657513AE631E58DD3DAA258815',
             '3C431091A9B1EA2820F825988196691B',
             '<KEY>ABA5',
             '56182A5C97E0D59839B96E481A4620B2',
             '8B14523C32A9B466F4E7F4C74ED49881',
             '927AAF474D2FDD8CD1078AE21C93C4A2',
             '95196AD021FC66472D2EE40CDF5085B0',
             'A3BD5B9F3000E7DE0D75E2B3406A3095',
             'ABAD62CA6078EA4BC4F0203B543BA466',
             'b168f0f724ba16669de939f8fe7722a4',
             'B290347517E9946AE25925CEAFCC44B0',
             'B631EA20192B2D18230EAEA141279C3A',
             'C3115190164380BD6D5EE8E523CA8FAE',
             'c94b82145989610f82d57f4b49cf4f5c',
             'CAEDB7644663EB2B5F581041E76682F3',
             'D7BBA8BC8DCDF9BB1E2099D4021ABE25',
             'EF41A70B672973DC38642945340A6F75',
             'F8875650D2023A55B0152CCF81C6134F',             
             'FADC181177F26E4F7B3DB4869444A3FB',
             'FF0028BFD604DC30DE65EEF93A19EB53',
                         '-L8Jf8bAKfsBghjCvW1i',
                         '-L84a-8IHZp7MecWO1CI']

users_exclude.extend(tester_keys)
users_exclude = list(set(users_exclude))

all_users = all_users[~(all_users.User.isin(users_exclude))]


all_users.reset_index(drop=True,inplace=True)
all_users.tail()<jupyter_output><empty_output><jupyter_text>Get study demographic info for participants<jupyter_code>def flatten_fill(user_data):
    
    Session = user_data.Session.dropna().min()
    
    email = user_data.Email.dropna().unique()
    email = ''.join(email)
    
    check_mobile = user_data.MobileNumber.dropna().unique()
    mobile = np.nan
    
    if('Empty' not in check_mobile):
        check_mobile = ''.join(check_mobile)
        mobile = check_mobile[0:2]
        if(len(mobile)==0):
            mobile = np.nan
    
    check_clincian = user_data.Doctor.dropna().unique()
    clinician = False
    
    if('Yes' in check_clincian):
        clinician = True
        
    check_etat = user_data.ETAT.dropna().unique()
    etat = False
    
    if('Yes' in check_etat):
        etat = True
    
    
    study_group = user_data.StudyGroup.dropna()
    study_group = study_group.astype(str).str.strip()
    study_group = study_group.unique()
    study_group = ''.join(study_group)    
    
    check_consent = user_data.ConsentGiven.dropna().unique()
    consent = True
    
    if('true' not in check_consent):
        consent = False    
    
    
    if not consent:
        user_details = pd.DataFrame({'Session':Session
                                     ,'Email':email
                                     ,'Country':mobile
                                     ,'Clinician':clinician
                                     ,'ETAT':etat
                                     ,'StudyGroup':study_group
                                     ,'ConsentGiven':consent
                                     ,'Institution':np.nan
                                     ,'Age':np.nan
                                     ,'Cadre':np.nan
                                     ,'Level':np.nan
                                     ,'Experience':np.nan
        }, index=user_data.User.unique())
            
    else:
        institution = user_data.Institution.dropna().unique()
        age = user_data.Age.dropna().unique()
        cadre = user_data.Cadre.dropna().unique()
        level = user_data.Level.dropna().unique()
        experience = user_data.Experience.dropna().unique()
        
        if(len(institution) == 0):
            institution = np.nan
        else:
            institution = ''.join(institution)
        if(len(age) == 0):
            age = np.nan
        else:
            age = ''.join(age)
        if(len(cadre) == 0):
            cadre = np.nan
        else:
            cadre = ''.join(cadre)
        if(len(level) == 0):
            level = np.nan
        else:
            level = ''.join(level)
        if(len(experience) == 0):
            experience = np.nan
        else:
            experience = ''.join(experience)          
            
        
        user_details = pd.DataFrame({'Session':Session
                                     ,'Email':email
                                     ,'Country':mobile
                                     ,'Clinician':clinician
                                     ,'ETAT':etat
                                     ,'StudyGroup':study_group
                                     ,'ConsentGiven':consent
                                     ,'Institution':institution
                                     ,'Age':age
                                     ,'Cadre':cadre
                                     ,'Level':level
                                     ,'Experience':experience
        }, index=user_data.User.unique())
    return user_details    
    

users_list=all_users.groupby('User').apply(flatten_fill)
users_list.reset_index(inplace=True)
users_list = users_list.drop('level_1',axis=1)


#Users missing record on users node
aberrant = pd.DataFrame({'Session': datetime.strptime('2019-03-06 17:37:05','%Y-%m-%d %H:%M:%S')
             ,'User':'703D7C0244D777F3EF9D756918231113'
             ,'Email':'Empty'
             ,'Country':'ke'
             ,'Clinician':True
             ,'ETAT':False
             ,'StudyGroup':1
             ,'ConsentGiven':True
             ,'Institution':np.nan
             ,'Age':np.nan
             ,'Cadre':np.nan
             ,'Level':np.nan
             ,'Experience':np.nan
        }, index=[users_list.shape[0]])
users_list = pd.concat([users_list,aberrant])

users_list = users_list.sort_values(by=['Session'],ascending=[True])
users_list = users_list.reset_index(drop=True)
users_list.loc[(users_list.Clinician==False)&(users_list.Cadre.isin(['Doctor','Nurse','Clinical Officer','DoctorNurse'])),['Clinician']]=True

users_list.tail()
##Aberrant user lists
users_crossover = users_list.User[users_list.StudyGroup.isin(['12','21'])]
print("Users so far: " + str(len(users_list.User)))
from collections import Counter
from hdx.location.country import Country

def get_country_region(code):
    return Country.get_country_info_from_iso2(code)['#region+main+name+preferred']

def get_country_details(code):
    return Country.get_country_info_from_iso2(code)

def get_country_sub_region(code):
    if isinstance(code,float):
        if np.isnan(code):
            return 'nan'
    else:
        return Country.get_country_info_from_iso2(str(code))['#region+name+preferred+sub']
    

country_list = users_list.Country.dropna().tolist()
country_list_sub = users_list.Country.tolist()
country_sub_region = [get_country_sub_region(i) for i in country_list_sub]

country_name = [get_country_details(i)['#country+name+preferred'] for i in country_list]
country_iso = [get_country_details(i)['#country+code+v_iso3'] for i in country_list]
country_region = [get_country_details(i)['#region+main+name+preferred'] for i in country_list]

users_list['Region'] = pd.Series(country_sub_region)
#country_list = [i.upper() for i in country_list]
country_region = [get_country_region(i) for i in country_list]
region_counts = Counter(country_region)
region_df = pd.DataFrame.from_dict(region_counts, orient='index').reset_index()
region_df.rename(columns={'index':'Region',0:'Counts'},inplace=True)

total = region_df.Counts.sum()

region_df['Percentage'] = np.round((region_df.Counts / total),4)

latitudes = [-15,50.3785,30.4507,2.3185,22.7359]
longitudes = [-60.4915,14.9706,75.8319,24.5687,140.0188]

region_df['Latitude'] = pd.Series(latitudes) 
region_df['Longitude'] = pd.Series(longitudes) 
region_df['Label'] = region_df.Region.astype(str) + " : "+ region_df.Counts.astype(str)
region_df


df_regions = pd.DataFrame(list(zip(
     country_name,
     country_iso,
     country_region)),
     columns =['countries','iso_alpha','continent']
)
df_regions.head()
df_regions = df_regions.groupby(['countries','iso_alpha','continent']).size()
df_regions = df_regions.to_frame()
df_regions.reset_index(inplace=True)
df_regions.rename(columns={0:'pop'},inplace=True)
df_regions.tail()
developing_countries =['nan','Northern Africa','Sub-Saharan Africa','Latin America and the Caribbean','Central Asia',
                       'Eastern Asia','South-eastern Asia','Western Asia','Melanesia','Micronesia','Polynesia']
users_developed_countries = users_list.User[~(users_list.Region.isin(developing_countries))].tolist()
import plotly.express as px
fig = px.scatter_geo(df_regions, locations="iso_alpha", color="continent",
                     hover_name="countries", size="pop",
                     projection="natural earth")
fig.show()
users_list.loc[users_list.StudyGroup=='',['StudyGroup']] = '-1'
users_list.StudyGroup = users_list.StudyGroup.astype(int)
users_groups = users_list.StudyGroup.value_counts()
fishy_users = users_list.User[~users_list.StudyGroup.isin([1,2])].unique().tolist()
users_groups = users_groups.to_frame()
users_groups.reset_index(inplace=True)
users_groups=users_groups.rename(columns={'index':'Group','StudyGroup':'Counts'})
users_groups_abberant = users_groups[~(users_groups.Group.isin([1,2]))]
users_groups_abberant
summary_recruit = users_list.groupby(['User','Clinician','ConsentGiven']).size()
summary_recruit = summary_recruit.to_frame()
summary_recruit.reset_index(inplace=True)
pd.crosstab(summary_recruit.ConsentGiven,summary_recruit.Clinician,margins=True,margins_name="Total")
pd.crosstab(summary_recruit.ConsentGiven,summary_recruit.Clinician,
            margins=True,margins_name="Total").apply(lambda r: round(r/len(summary_recruit),4)*100,axis=1)<jupyter_output><empty_output><jupyter_text>Get LIFE Play Data<jupyter_code>neonate_play = db.child("resus").child("play").get()
play_data = pd.DataFrame()
for play_node in neonate_play.each():
    user_id = play_node.key()
    if(user_id in users_exclude):
        continue
    else:        
        for key,entries in play_node.val().items():
            if(key=='scenario_a'):                
                for session_key,play_session in entries.items():
                    session = None
                    try:
                        session = datetime.strptime(session_key, '%b %d, %Y, %I:%M:%S %p')
                    except:
                        continue
                    for _,play_stats in play_session.items():
                        stats = play_stats.split(',')
                        stats[0]=stats[0].replace("Question","")
                        if(len(stats)>4):
                            row_cols = ["User","Session","Question","Try","Time","Correct","Feedback"]
                            row_vals=[user_id,session]
                            row_vals.extend(stats)                
                            play_row = pd.DataFrame.from_records([row_vals],columns=row_cols)
                            play_data = pd.concat([play_data,play_row])
            
play_data.Question=play_data.Question.astype(int)
play_data = play_data[play_data.Question != 6]
play_data.Try=play_data.Try.astype(int)
play_data.Correct=play_data.Correct.astype(int)
play_data.Time=play_data.Time.astype(float)
play_data.Time=play_data.Time.round(3)

#play_data = play_data[play_data.User.isin(users_list.User)]
play_data.to_csv(ROOT_DATA+'play_data_raw.csv')
srl_play_data = play_data.copy()
srl_play_data.Session = pd.to_datetime(srl_play_data.Session)
srl_play_data = srl_play_data[srl_play_data.Session < '2019-08-01 00:00:01']
srl_play_data = srl_play_data[srl_play_data.Session > '2019-02-06 23:59:59']
##Fix users with missing records
missing_user_record = play_data.User[~(play_data.User.isin(users_list.User))].unique().tolist()
include_missing = pd.DataFrame()

for i in missing_user_record:
    earliest_session = play_data.Session[play_data.User==i].min()
    study_group = '1'
    feedback = play_data.Feedback[play_data.User==i].unique().tolist()
    if '1' in feedback:
        study_group='2'
    aberrant = pd.DataFrame({'Session': earliest_session
             ,'User':i
             ,'Email':'Empty'
             ,'Country':'ke'
             ,'Clinician':True
             ,'ETAT':False
             ,'StudyGroup':study_group
             ,'ConsentGiven':False
             ,'Institution':np.nan
             ,'Age':np.nan
             ,'Cadre':np.nan
             ,'Level':np.nan
             ,'Experience':np.nan
        }, index=[users_list.shape[0]])
    include_missing = pd.concat([include_missing,aberrant])
    
play_data_missing = play_data[play_data.User.isin(missing_user_record)]
include_missing.reset_index(drop=True,inplace=True)
users_list = pd.concat([users_list,include_missing])
users_list.reset_index(drop=True,inplace=True)<jupyter_output><empty_output><jupyter_text>Filters for remaining with study-appropriate records<jupyter_code>users_to_track_mask = (users_list['ConsentGiven']==True)&(users_list['Clinician']==True)
healthworkers_mask = (users_list['Clinician']==True)
hw_to_track = users_list.User[healthworkers_mask].unique() #Study participants
users_to_track = users_list.User[users_to_track_mask].unique() #Study participants<jupyter_output><empty_output><jupyter_text>Fix sessionnless users from play data<jupyter_code>#Fix sessionless users
users_sessionless = users_list.User[users_list.Session.isna()]
for i in users_sessionless:
    earliest_time = play_data.Session[play_data.User==i].min()
    if not str(earliest_time)=="NaT":
        users_list.loc[users_list.User==i,['Session']] = earliest_time
print("Users still missing session data: {}".format(len(users_list.User[users_list.Session.isna()].tolist())))<jupyter_output>Users still missing session data: 202<jupyter_text>Deal with bug: writes multiple copies of records to _Google firebase_<jupyter_code>play_data['Repeated'] = 0.0
play_data['I'] = 1.0
play_data.Repeated = play_data.groupby(['User','Session','Question','Try']).I.cumcount()
play_data_repeated = play_data.copy()
play_data.drop('I',axis=1,inplace=True)
play_data_repeated.drop('I',axis=1,inplace=True)
play_data_repeated.reset_index(inplace=True,drop=True)
play_data.reset_index(inplace=True,drop=True)
play_data_repeated.tail()
new_session_start = play_data_repeated.groupby(['User','Session','Repeated']).Time.sum()
new_session_start = new_session_start.to_frame()
new_session_start.reset_index(inplace=True)
new_session_start['Next_Session'] = new_session_start.Session
new_session_start.tail()
for index,row in new_session_start.iterrows():
    current_repeat, user, current_session = row['Repeated'], row['User'], row['Session']
    previous_repeat = current_repeat-1
    if(current_repeat == 1):
        last_session = new_session_start.Session[(new_session_start.User==user)&(new_session_start.Repeated==previous_repeat)&(new_session_start.Session==current_session)].tolist()
        last_session = list(set(last_session))[0]
        last_time = new_session_start.Time[(new_session_start.User==user)&(new_session_start.Repeated==previous_repeat)&(new_session_start.Session==current_session)].tolist()
        last_time = list(set(last_time))[0]
        new_session = last_session + timedelta(seconds=np.ceil(last_time)) + timedelta(seconds=3)
        new_session_start.loc[index,['Next_Session']] = new_session
    
    elif(current_repeat > 1):
        last_session = new_session_start.Next_Session[(new_session_start.User==user)&(new_session_start.Repeated==previous_repeat)&(new_session_start.Session==current_session)].tolist()
        last_session = list(set(last_session))[0]
        last_time = new_session_start.Time[(new_session_start.User==user)&(new_session_start.Repeated==previous_repeat)&(new_session_start.Session==current_session)].tolist()
        last_time = list(set(last_time))[0]
        new_session = last_session + timedelta(seconds=np.ceil(last_time)) + timedelta(seconds=3)
        new_session_start.loc[index,['Next_Session']] = new_session
    
    
new_session_start.drop('Time',axis=1,inplace=True)
play_data_fixed = pd.merge(play_data,new_session_start,how='left',on=['User','Session','Repeated'])
play_data_fixed.Session = play_data_fixed.Next_Session
play_data_fixed.drop(['Repeated','Next_Session'],axis=1,inplace=True)
play_data_test = play_data_fixed.groupby(['User','Session','Question','Try']).first()
play_data_test.reset_index(inplace=True)

play_data = play_data_fixed

play_data.reset_index(drop=True,inplace=True)
play_data=play_data.sort_values(by=['Session','User','Question'],ascending=[True,False,True])
play_data.head()<jupyter_output><empty_output><jupyter_text>Keep records that are covered by ethical approval and study protocol<jupyter_code>play_data = play_data[play_data.Session < '2019-08-01 00:00:01']
play_data = play_data[play_data.Session > '2019-02-06 23:59:59']
play_data = play_data.reset_index(drop=True)
users_list.StudyGroup = users_list.StudyGroup.astype(str)
users_list.StudyGroup = users_list.StudyGroup.astype(int)
print("Users assessed for eligibility: " +str(len(play_data.User.unique().tolist())))
srl_play_data = play_data.copy()
users_should_be_experiment = play_data.User[(play_data.Correct==0)&(play_data.Feedback=='1')].unique().tolist()
users_reg_control = users_list.User[users_list.StudyGroup==1].unique().tolist()
other_fishy_users = list(set(users_reg_control).intersection(users_should_be_experiment))
fishy_users.extend(other_fishy_users)

play_data = play_data[~(play_data.User.isin(fishy_users))] #Exclude users with mixed study groups
print("Exclude Users with cross-over: " +str(len(play_data.User.unique().tolist())))
play_data = play_data[~(play_data.User.isin(users_developed_countries))] 
srl_play_data = srl_play_data[~(srl_play_data.User.isin(users_developed_countries))] 
print("Exclude Users from HIC: " +str(len(play_data.User.unique().tolist())))
play_data = play_data[(play_data.User.isin(hw_to_track))] #Exclude users with mixed study groups
srl_play_data = srl_play_data[(srl_play_data.User.isin(hw_to_track))] 
print("Exclude users not healthcare workers: " +str(len(play_data.User.unique().tolist())))
srl_play_data = srl_play_data[~(srl_play_data.User.isin(users_developed_countries))] 
srl_play_data = srl_play_data[(srl_play_data.User.isin(hw_to_track))] 
srl_play_data.User.nunique()
play_data = play_data.reset_index(drop=True)
play_data.reset_index(inplace=True,drop=True)
play_data.tail()
users_list = users_list[users_list.User.isin(srl_play_data.User)]
users_list.reset_index(drop=True,inplace=True)
users_list.tail()<jupyter_output><empty_output><jupyter_text>Tag completed learning sessions<jupyter_code>play_completed=play_data.groupby(['User','Session']).Question.agg('nunique').reset_index(name="Quiz_Attempted")
play_completed['Session_Complete']=np.where(play_completed.Quiz_Attempted==10,1,0)
play_data = pd.merge(play_data,play_completed,how='left',on=['User','Session'])
play_data.tail()
play_repeat=play_data.drop_duplicates(['User','Session','Session_Complete'])
complete_plays=play_repeat.groupby(['User']).Session_Complete.agg('sum')
complete_plays = complete_plays.to_frame()
complete_plays.reset_index(inplace=True)
complete_plays = complete_plays.rename(columns={"Session_Complete": "Complete_Plays"})
play_data = pd.merge(play_data,complete_plays,how='left',on=['User'])
play_data.tail()
play_incomplete = play_data[play_data.Complete_Plays==0]

keep_question = play_incomplete[['User','Session','Quiz_Attempted','Question']]
keep_question = keep_question.drop_duplicates(['User','Session','Quiz_Attempted','Question'])
keep_question = keep_question.groupby(['User','Session','Quiz_Attempted']).Question.max()
keep_question = keep_question.to_frame()
keep_question.reset_index(inplace=True)

play_incomplete = play_incomplete.groupby(['User','Session','Quiz_Attempted']).Time.sum()
play_incomplete = play_incomplete.to_frame()
play_incomplete.reset_index(inplace=True)

play_incomplete = pd.merge(play_incomplete,keep_question,how='left',on=['User','Session','Quiz_Attempted'])


upto = play_incomplete.Question.unique().tolist()
upto.sort()
i = 0
data = [None] * len(upto)

for j in upto:
    lbl = i+1
    cmd="trace"+str(lbl)+"=go.Box(x=play_incomplete.Time[play_incomplete.Question=="+str(j)+"],name='"+str(j)+"')"
    exec(cmd)
    cmd="data["+str(i)+"]=trace"+str(lbl)
    exec(cmd)
    i = lbl

layout = {"title": "Time spent in learning session before drop-out", 
          "xaxis": {"title": "Time in Seconds" }, 
          "yaxis": {"title": "Quiz up to"},
          "showlegend": False,
          "font" :{"family":"Corbel","size":18,"color":"#7f7f7f"},
         }

fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='time-dropout-plot')
play_incomplete = play_data[['User','Quiz_Attempted','Complete_Plays']]
play_incomplete = play_incomplete.drop_duplicates(['User','Quiz_Attempted','Complete_Plays'])
play_incomplete = play_incomplete[play_incomplete.Complete_Plays==0]
play_upto = play_incomplete.groupby(['User'], sort=False)['Quiz_Attempted'].max()
play_upto = play_upto.to_frame()
play_upto.reset_index(inplace=True)

omit_users = play_data.User[play_data.Complete_Plays > 0].dropna().unique()
play_upto = play_upto[~(play_upto.User.isin(omit_users))]

###Replace with actual quiz count
quizzes = {9:12}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {8:10}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {7:9}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {6:7}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
play_upto['Quiz'] = "Q"+ play_upto.Quiz_Attempted.astype(str)
play_upto.Quiz = pd.Categorical(play_upto.Quiz,categories=['Q1','Q2','Q3','Q4','Q5','Q7','Q9','Q10','Q12'],ordered=True)


Attempt_Upto = play_upto.groupby('Quiz').User.agg('size')
Attempt_Upto = Attempt_Upto.to_frame()
Attempt_Upto.reset_index(inplace=True)

Attempt_Upto['Upto'] = Attempt_Upto.User.cumsum()

Attempt_Upto['Running_Pct'] = Attempt_Upto.Upto.transform(lambda x: round(x / x.iloc[-1],4))
Attempt_Upto.Running_Pct = Attempt_Upto.Running_Pct * 100
Attempt_Upto.Running_Pct = round(Attempt_Upto.Running_Pct,2)
Attempt_Upto['Running_Pct_lbl'] = Attempt_Upto.Running_Pct.astype(str) + '%'
Attempt_Upto['lbl_txt'] = Attempt_Upto.User.astype(str)+' ('+Attempt_Upto.Upto.astype(str)+')'

trace1 = go.Bar(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Upto,
            text = Attempt_Upto.lbl_txt,
            textposition = 'outside',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18
            ),
            name='No. Users (Cumilative)'
        )

trace2 = go.Scatter(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Running_Pct,
            mode = 'lines+markers+text',
            text = Attempt_Upto.Running_Pct_lbl,
            textposition = 'bottom center',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#ff7f0e'
            ),
            name='Cumilative %',
            yaxis='y2'
        )

data = [trace1, trace2]

layout = go.Layout(
    title='LIFE drop-out rate by users \nwithout complete session*',
    xaxis=dict(title='Attempted up to Quiz',
               categoryorder='array',
               categoryarray=['Q1','Q2','Q3','Q4','Q5','Q7','Q9','Q10','Q12']),
    yaxis=dict(title='Drop-out Count'),
    yaxis2=dict(
        title='Drop-out %',
        titlefont=dict(
            color='#ff7f0e'
        ),
        tickfont=dict(
            color='#ff7f0e'
        ),
        overlaying='y',
        side='right',
        showgrid=False,        
    ),
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',
                xanchor='center',
                yanchor='top',
                y=-0.25,
                x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'dropout-compare-users')
play_incomplete = play_data[['User','Session','Quiz_Attempted','Complete_Plays']]
play_incomplete = play_incomplete.drop_duplicates(['User','Session','Quiz_Attempted','Complete_Plays'])
play_incomplete = play_incomplete[play_incomplete.Complete_Plays==0]
play_upto = play_incomplete.groupby(['User','Session'], sort=False)['Quiz_Attempted'].max()
play_upto = play_upto.to_frame()
play_upto.reset_index(inplace=True)

omit_users = play_data.User[play_data.Complete_Plays > 0].dropna().unique()
play_upto = play_upto[~(play_upto.User.isin(omit_users))]

###Replace with actual quiz count
quizzes = {9:12}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {8:10}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {7:9}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {6:7}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
play_upto['Quiz'] = "Q"+ play_upto.Quiz_Attempted.astype(str)
play_upto.Quiz = pd.Categorical(play_upto.Quiz,categories=['Q1','Q2','Q3','Q4','Q5','Q7','Q9','Q10','Q12'],ordered=True)


Attempt_Upto = play_upto.groupby('Quiz').Session.agg('size')
Attempt_Upto = Attempt_Upto.to_frame()
Attempt_Upto.reset_index(inplace=True)
Attempt_Upto['Upto'] = Attempt_Upto.Session.cumsum()

Attempt_Upto['Running_Pct'] = Attempt_Upto.Upto.transform(lambda x: round(x / x.iloc[-1],4))
Attempt_Upto.Running_Pct = Attempt_Upto.Running_Pct * 100
Attempt_Upto.Running_Pct = round(Attempt_Upto.Running_Pct,2)
Attempt_Upto['Running_Pct_lbl'] = Attempt_Upto.Running_Pct.astype(str) + '%'
Attempt_Upto['lbl_txt'] = Attempt_Upto.Session.astype(str)+' ('+Attempt_Upto.Upto.astype(str)+')'
trace1 = go.Bar(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Upto,
            text = Attempt_Upto.lbl_txt,
            textposition = 'outside',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18
            ),
            name='No. Sessions (Cumilative)'
        )

trace2 = go.Scatter(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Running_Pct,
            mode = 'lines+markers+text',
            text = Attempt_Upto.Running_Pct_lbl,
            textposition = 'bottom center',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#ff7f0e'
            ),
            name='Cumilative %',
            yaxis='y2'
        )

data = [trace1, trace2]

layout = go.Layout(
    title='LIFE drop-out rate by sessions\n(Users without complete session)',
    xaxis=dict(title='Attempted up to Quiz'),
    yaxis=dict(title='Drop-out Count'),
    yaxis2=dict(
        title='Drop-out %',
        titlefont=dict(
            color='#ff7f0e'
        ),
        tickfont=dict(
            color='#ff7f0e'
        ),
        overlaying='y',
        side='right',
        showgrid=False,        
    ),
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',
                xanchor='center',
                yanchor='top',
                y=-0.25,
                x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'dropout-compare-sessions-incomplete')
play_incomplete_perf = play_data[['User','Session','Question','Try','Correct','Quiz_Attempted','Session_Complete']]
play_incomplete_perf = play_incomplete_perf[play_incomplete_perf.Session_Complete==0]
play_incomplete_perf.drop('Session_Complete',axis=1,inplace=True)

def cumilative_perf(user_data):
    number_quizzes = user_data.Quiz_Attempted.unique().tolist()[0]
    first_try = user_data.Correct[user_data.Try==1].tolist()
    score = np.sum(first_try)
    perf = round(score/number_quizzes,2)
    return perf
    
play_upto_perf = play_incomplete_perf.groupby(['User','Session','Quiz_Attempted']).apply(cumilative_perf)
play_upto_perf = play_upto_perf.to_frame()
play_upto_perf.reset_index(inplace=True)
play_upto_perf.rename(columns={0:'Score'},inplace=True)
play_upto_perf.drop(['User','Session'],axis=1,inplace=True)

play_upto_perf_se = play_upto_perf.groupby('Quiz_Attempted').agg({
    'Score': lambda x: x.std()/np.sqrt(x.count())
})
play_upto_perf_mean = play_upto_perf.groupby('Quiz_Attempted').agg({
    'Score': lambda x: round(x.mean(),4)
})

play_upto_perf_se.reset_index(inplace=True)
play_upto_perf_se.rename(columns={'Score':'SE'},inplace=True)
play_upto_perf_mean.reset_index(inplace=True)
play_upto_perf_mean.rename(columns={'Score':'Mean'},inplace=True)

play_upto_perf = pd.merge(play_upto_perf_mean,play_upto_perf_se,how='inner',on=['Quiz_Attempted'])
play_upto_perf['UI'] = play_upto_perf.Mean + (play_upto_perf.SE * 1.96)
play_upto_perf['LI'] = play_upto_perf.Mean - (play_upto_perf.SE * 1.96)
play_upto_perf['Score'] = play_upto_perf.Mean*100
play_upto_perf['UE'] = round(play_upto_perf.UI*100,2)
play_upto_perf['LE'] = round(play_upto_perf.LI*100,2)

###Replace with actual quiz count
quizzes = {9:12}
play_upto_perf = play_upto_perf.replace({'Quiz_Attempted': quizzes})
quizzes = {8:10}
play_upto_perf = play_upto_perf.replace({'Quiz_Attempted': quizzes})
quizzes = {7:9}
play_upto_perf = play_upto_perf.replace({'Quiz_Attempted': quizzes})
quizzes = {6:7}
play_upto_perf = play_upto_perf.replace({'Quiz_Attempted': quizzes})
play_upto_perf['Quiz'] = "Q"+ play_upto_perf.Quiz_Attempted.astype(str)
play_upto_perf.Quiz=pd.Categorical(play_upto_perf.Quiz,categories=['Q1','Q2','Q3','Q4','Q5','Q7','Q9','Q10','Q12'],ordered=True)
#play_upto = play_upto.to_frame()
#play_upto.reset_index(inplace=True)
#play_incomplete_perf.head()
play_upto_perf['Running_Pct_Score_lbl'] = round(play_upto_perf.Score,2).astype(str) + '%'
play_upto_perf
play_incomplete = play_data[['User','Session','Quiz_Attempted','Session_Complete']]
play_incomplete = play_incomplete.drop_duplicates(['User','Session','Quiz_Attempted','Session_Complete'])
play_incomplete = play_incomplete[play_incomplete.Session_Complete==0]
play_upto = play_incomplete.groupby(['User','Session'], sort=False)['Quiz_Attempted'].max()
play_upto = play_upto.to_frame()
play_upto.reset_index(inplace=True)

###Replace with actual quiz count
quizzes = {9:12}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {8:10}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {7:9}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
quizzes = {6:7}
play_upto = play_upto.replace({'Quiz_Attempted': quizzes})
play_upto['Quiz'] = "Q"+ play_upto.Quiz_Attempted.astype(str)
play_upto.Quiz = pd.Categorical(play_upto.Quiz,categories=['Q1','Q2','Q3','Q4','Q5','Q7','Q9','Q10','Q12'],ordered=True)



Attempt_Upto = play_upto.groupby('Quiz').Session.agg('size')
Attempt_Upto = Attempt_Upto.to_frame()
Attempt_Upto.reset_index(inplace=True)
Attempt_Upto['Upto'] = Attempt_Upto.Session.cumsum()

Attempt_Upto['Running_Pct'] = Attempt_Upto.Upto.transform(lambda x: round(x / x.iloc[-1],4))
Attempt_Upto.Running_Pct = Attempt_Upto.Running_Pct * 100
Attempt_Upto.Running_Pct = round(Attempt_Upto.Running_Pct,2)
Attempt_Upto['Running_Pct_lbl'] = Attempt_Upto.Running_Pct.astype(str) + '%'
Attempt_Upto['lbl_txt'] = Attempt_Upto.Session.astype(str)+' ('+Attempt_Upto.Upto.astype(str)+')'

play_upto_perf['Upto'] = Attempt_Upto.Upto
play_upto_perf['lbl_txt'] = Attempt_Upto.lbl_txt

play_upto_perf['Running_Pct'] = Attempt_Upto.Running_Pct
play_upto_perf['Running_Pct_lbl'] = Attempt_Upto.Running_Pct_lbl
play_upto_perf['Participants'] = play_upto_perf.Upto - play_upto_perf.Upto.shift(1)
play_upto_perf['Participants'][0]= play_upto_perf.Upto[0]
play_upto_perf.Participants = (round(play_upto_perf.Participants / play_upto_perf.Participants.sum(),4))*100
trace1 = go.Bar(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Upto,
            text = Attempt_Upto.lbl_txt,
            textposition = 'outside',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18
            ),
            name='No. Sessions (Cumilative)'
        )

trace2 = go.Scatter(
            x = Attempt_Upto.Quiz,
            y = Attempt_Upto.Running_Pct,
            mode = 'lines+markers+text',
            text = Attempt_Upto.Running_Pct_lbl,
            textposition = 'bottom center',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#ff7f0e'
            ),
            name='Cumilative %',
            yaxis='y2'
        )

data = [trace1, trace2]

layout = go.Layout(
    title='LIFE drop-out rate by sessions \n(All users)',
    xaxis=dict(title='Attempted up to Quiz'),
    yaxis=dict(title='Drop-out Count'),
    yaxis2=dict(
        title='Drop-out %',
        titlefont=dict(
            color='#ff7f0e'
        ),
        tickfont=dict(
            color='#ff7f0e'
        ),
        overlaying='y',
        side='right',
        showgrid=False,        
    ),
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',
                xanchor='center',
                yanchor='top',
                y=-0.25,
                x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'dropout-compare-sessions-all')
trace1 = go.Scatter(
            x = play_upto_perf.Quiz,
            y = play_upto_perf.Participants,
            #text = play_upto_perf.lbl_txt,
            mode = 'lines+markers+text',
            #textposition = 'outside',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#1F77B4'
            ),
            name="Participant's drop-out rate"
        )

trace2 = go.Scatter(
            x = play_upto_perf.Quiz,
            y = play_upto_perf.Score,
            mode = 'lines+markers+text',
            #text = play_upto_perf.Running_Pct_Score_lbl,
            #textposition = 'top center',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#ff7f0e'
            ),
            name='Performance(Running)',
            yaxis='y2'
        )

data = [trace1, trace2]

layout = go.Layout(
    title='LIFE running performance over drop-out rate \nby sessions (All users)',
    xaxis=dict(title='Attempted up to Quiz'),
    yaxis=dict(
        title='Drop-out rate (%)',
        titlefont=dict(
            color='#1F77B4'
        ),
        tickfont=dict(
            color='#1F77B4'
        ),
    ),
    yaxis2=dict(
        title='Performance (Running) %',
        titlefont=dict(
            color='#ff7f0e'
        ),
        tickfont=dict(
            color='#ff7f0e'
        ),
        overlaying='y',
        side='right',
        showgrid=False,        
    ),
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',
                xanchor='center',
                yanchor='top',
                y=-0.25,
                x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'dropout-compare-perf')
users_list.loc[users_list.Cadre=='DoctorNurse',['Cadre']]='Nurse'
users_list.loc[users_list.Cadre=='NurseDoctor',['Cadre']]='Nurse'
users_list.loc[users_list.Cadre=='Clinical OfficerDoctor',['Cadre']]='Clinical Officer'
user_cadre = users_list.Cadre[users_list.User.isin(play_data.User)].dropna()
cadre_df = user_cadre.value_counts().rename_axis('Clinical_Cadre').reset_index(name='Counts')
total_cadre = cadre_df.Counts.sum()
cadre_df['Percent'] = np.round((cadre_df.Counts/total_cadre)*100,2) 
cadre_df
trace1 = go.Bar(
            x = cadre_df.Clinical_Cadre,
            y = cadre_df.Counts,
            text = cadre_df.Percent.astype(str) + str(" %"),
            textposition = 'outside',
            cliponaxis=False,
            textfont=dict(
                family='Corbel',
                size=18,
                color='#ff7f0e'
            )
        )

data = [trace1]

layout = go.Layout(
    title='LIFE users by clinical cadre',
    xaxis=dict(title='Clinical Cadre'),
    yaxis=dict(title='User Count'),    
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',
                xanchor='center',
                yanchor='top',
                y=-0.25,
                x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'life-cadre-users')
play_feed_compare= play_data[~((play_data.Try==1)&(play_data.Correct==1))]
play_feed_compare = play_feed_compare.drop(['Time','Quiz_Attempted','Session_Complete','Complete_Plays'],axis=1)
play_feed_compare['Next_Try_Correct'] = 0
count_missing = 0

for index, row in play_feed_compare.iterrows():
    user,session,quiz,quiz_try = row['User'],row['Session'],row['Question'],row['Try']
    next_try = quiz_try + 1
    if((play_feed_compare.User==user)&(play_feed_compare.Session==session)&(play_feed_compare.Question==quiz)&(play_feed_compare.Try==next_try)).any():
        answered_correctly = list(set(play_feed_compare.Correct[(play_feed_compare.User==user)&(play_feed_compare.Session==session)&(play_feed_compare.Question==quiz)&(play_feed_compare.Try==next_try)].tolist()))
        if len(answered_correctly) > 1:
            print(user)
            print(session)
            print(quiz)
            print(quiz_try)
            
        play_feed_compare.loc[index,'Next_Try_Correct'] = answered_correctly
    else:
        play_feed_compare.loc[index,'Next_Try_Correct'] = np.nan

play_feed_compare = play_feed_compare[~(play_feed_compare.Correct==1)]
no_info = play_feed_compare[np.isnan(play_feed_compare.Next_Try_Correct)]
print("Missing information: ", no_info.shape[0])
play_feed_compare = play_feed_compare[~(np.isnan(play_feed_compare.Next_Try_Correct))]
play_feed_compare.Next_Try_Correct = play_feed_compare.Next_Try_Correct.astype(int)
play_feed_compare.tail()
from scipy.stats import chi2_contingency
#chi2, p, dof, expected = chi2_contingency(feedback_effect)

print("======== Feedback effect ========")
#print("χ2: %f" % chi2)
#print("P-value: %f" % p)
#print("Degrees of freedom: %d" % dof)
print("=================================")<jupyter_output>======== Feedback effect ========
=================================<jupyter_text>>When testing the data, the cells should be counts of cases and not percentages. It is okay to convert to percentages after testing the data1. The levels (groups) of the variables being tested are mutually exclusive2. Each participant contributes to only one cell within the Chi-square table3. The groups being tested must be independentDon't use the value above, it contravenes these rules<jupyter_code>feedback_matrix =  play_feed_compare.drop(['User','Session','Try'],axis=1)
summary_feed_plot = feedback_matrix.groupby(['Question','Feedback']).agg({'Correct':'size',
                                                                         'Next_Try_Correct':'sum'})
summary_feed_plot.reset_index(inplace=True)
summary_feed_plot['Performance_Rate'] = np.round((summary_feed_plot.Next_Try_Correct/
                                                  summary_feed_plot.Correct)*100,2)
summary_feed_plot.Question = 'Q'+summary_feed_plot.Question.astype(str)
summary_feed_plot_0 = summary_feed_plot[summary_feed_plot.Feedback=='0']
summary_feed_plot_1 = summary_feed_plot[summary_feed_plot.Feedback=='1']
summary_feed_plot_2 = summary_feed_plot[summary_feed_plot.Feedback=='2']

trace0 = go.Bar(
            x = summary_feed_plot_0.Question,
            y = summary_feed_plot_0.Performance_Rate,
            text = summary_feed_plot_0.Performance_Rate,
            textposition = 'auto',
            textfont=dict(
                family='Corbel',
                size=16
            ),
            name = 'Feedback: Retry'
        )

trace1 = go.Bar(
            x = summary_feed_plot_1.Question,
            y = summary_feed_plot_1.Performance_Rate,
            text = summary_feed_plot_1.Performance_Rate,
            textposition = 'auto',
            textfont=dict(
                family='Corbel',
                size=16
            ),
            name = 'Feedback: Reflective'
        )

trace2 = go.Bar(
            x = summary_feed_plot_2.Question,
            y = summary_feed_plot_2.Performance_Rate,
            text = summary_feed_plot_2.Performance_Rate,
            textposition = 'auto',
            textfont=dict(
                family='Corbel',
                size=18
            ),
            name = 'Feedback: Detailed'
        )

data = [trace0, trace1, trace2]

layout = go.Layout(
    title='Performance rate after feedback',
    xaxis=dict(title='Quizzes'),
    yaxis=dict(title='% Correct'),
    barmode='group',
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
    legend=dict(orientation='h',xanchor='center',yanchor='top',y=-0.25,x=0.5)
)

fig = go.Figure(data=data, layout=layout)

py.iplot(fig, filename = 'feedback-compare')
play_recruit=play_data.drop_duplicates(['User','Session'])
users_entry = play_recruit.groupby('User').Session.first()
recruit_users = users_entry.to_frame().reset_index()
recruit_users.Session = pd.to_datetime(recruit_users.Session)
recruit_users['Date'] = recruit_users.Session.dt.date
recruit_users['Day_Week'] = recruit_users.Session.dt.day_name()
rectuit_users_series=recruit_users.groupby(['Date']).Day_Week.agg(
    #'Count':'count'
    Count = pd.NamedAgg(column='Count',aggfunc='count')
).reset_index()

recruit_cycle=play_recruit.Session.value_counts()
recruit_cycle=recruit_cycle.to_frame().reset_index()

recruit_cycle=recruit_cycle.rename(columns={'index':'Day','Session':'Counts'})
recruit_cycle.Day = pd.to_datetime(recruit_cycle.Day)
recruit_cycle['Date'] = recruit_cycle.Day.dt.date
recruit_cycle['Day_Week'] = recruit_cycle.Day.dt.day_name()
rectuit_cycle_series=recruit_cycle.groupby(['Date','Day_Week']).Day.agg(
     Count = pd.NamedAgg(column='Count',aggfunc='count')
).reset_index()
rectuit_cycle_wkd = rectuit_cycle_series.Date[rectuit_cycle_series.Day_Week.isin(['Saturday'])]
rectuit_cycle_wkd

start_date = datetime.strptime('2019-02-09','%Y-%m-%d')
curr_date = datetime.strptime('2019-08-01','%Y-%m-%d')
date_list = [start_date + timedelta(days=x) for x in range((curr_date-start_date).days + 1) if (start_date + timedelta(days=x)).weekday() == 5]

#recruit_users.head()
#rectuit_users_series

trace1 = go.Scatter(x=rectuit_users_series.Date, 
                    y=rectuit_users_series.Count,
                    mode='lines+markers+text',
                    #text=rectuit_users_series.Count,
                    textposition = 'top center',
                    name='Users')

trace2 = go.Scatter(x=rectuit_cycle_series.Date, 
                    y=rectuit_cycle_series.Count,
                    mode='lines+markers+text',
                    #text=rectuit_cycle_series.Count,
                    textposition = 'top center',
                    name='Sessions')


data = [trace1, trace2]
layout = {
    'xaxis': {
        'range': [datetime.date(min(rectuit_cycle_series.Date)-pd.DateOffset(1)),curr_date]
    },
    'yaxis': {
        'range': [0, max(rectuit_cycle_series.Count)+1]
    },
    'shapes':[{'type':'rect',
               'x0':x,
               'y0':0,
               'x1':datetime.date(x+pd.DateOffset(1)),
               'y1':70,
               'line':{'color':'rgba(128,0,128,1)','width':0.1},
               'fillcolor':'rgba(128,0,128,0.1)'} for x in date_list],
    'title':'LIFE game-play sessions over time',
    'xaxis':{'title':'Time'},
    'yaxis':{'title':'Session counts'},
    'font' :{'family':'Corbel','size':18,'color':'#7f7f7f'},
}

fig = {
    'data': data,
    'layout': layout,
}

py.iplot(fig, filename = 'time-series-recruit')

play_time_day =  play_data[['User','Session']]
play_time_day = play_time_day.drop_duplicates(['User','Session'])
play_time_day.Session = pd.to_datetime(play_time_day.Session)
play_time_day['Day_Week'] = play_time_day.Session.dt.day_name()
day_of_week = play_time_day.groupby('Day_Week').size()
day_of_week = day_of_week.to_frame()
day_of_week.reset_index(inplace=True)
day_of_week = day_of_week.rename(columns={0:'Count'})
day_of_week.Day_Week = pd.Categorical(day_of_week.Day_Week,ordered=True,
                                      categories=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'])

regulate_learn = [go.Bar(
    x = day_of_week.Day_Week,
    y = day_of_week.Count,
    text = day_of_week.Count,
    textposition = 'auto',
    textfont=dict(family='Corbel',size=18 )
)]

layout = go.Layout(
    title='LIFE play-time sessions',
    xaxis=dict(title='Day of the week',
              categoryarray=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']),
    yaxis=dict(title='Count of sessions \nfrom unique users'),    
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
)

py.iplot(go.Figure(data=regulate_learn,layout=layout), filename='time-track-day')
play_time_day =  play_data[['User','Session']]
play_time_day = play_time_day.drop_duplicates(['User','Session'])
play_time_day.Session = pd.to_datetime(play_time_day.Session)
play_time_day['Hour_of_Day'] = play_time_day.Session.dt.hour
time_of_day = play_time_day.groupby('Hour_of_Day').size()
time_of_day = time_of_day.to_frame()
time_of_day.reset_index(inplace=True)
time_of_day = time_of_day.rename(columns={0:'Count'})
time_of_day

regulate_learn = [go.Bar(
    x = time_of_day.Hour_of_Day,
    y = time_of_day.Count)]

layout = go.Layout(
    title='LIFE play-time sessions',
    xaxis=dict(title='Hour of the day',
               tickmode='linear',
               ticks='outside',
               tick0=0,
               dtick=1),
    yaxis=dict(title='Count of sessions \nfrom unique users'),    
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
)

py.iplot(go.Figure(data=regulate_learn,layout=layout), filename='time-track-time')<jupyter_output><empty_output><jupyter_text>Temporal pattern of randomisation ratio<jupyter_code>first_time_random = play_time_day.groupby('User').first()
first_time_random.reset_index(inplace=True)
first_time_random['Day_Week'] = first_time_random.Session.dt.day_name()
first_time_random['Month_Year'] = first_time_random.Session.dt.month_name()

learners_group = users_list[['User','StudyGroup']]
learners_group = learners_group.drop_duplicates(['User','StudyGroup'])
learners_group = pd.merge(learners_group,first_time_random,how='left',on='User')
learners_group.rename(columns={'StudyGroup':'Group'},inplace=True)
learners_group.Group = learners_group.Group.astype(str)
learners_group.loc[learners_group.Group=='1',['Group']] = 'Control'
learners_group.loc[learners_group.Group=='2',['Group']] = 'Experiment'
learners_group.head()
hour_randomisation = learners_group.groupby(['Group','Hour_of_Day']).User.count()
hour_randomisation = hour_randomisation.to_frame()
hour_randomisation.reset_index(inplace=True)
hour_randomisation_ctrl = hour_randomisation.iloc[range(0,24)]
hour_randomisation_ctrl.drop('Group',axis=1,inplace=True)
hour_randomisation_ctrl.rename(columns={'User':'Control'},inplace=True)
hour_randomisation_exp = hour_randomisation.iloc[range(24,47)]
hour_randomisation_exp.drop('Group',axis=1,inplace=True)
hour_randomisation_exp.rename(columns={'User':'Experiment'},inplace=True)
hour_randomisation_all = pd.merge(hour_randomisation_ctrl,hour_randomisation_exp,on='Hour_of_Day',how='outer')
hour_randomisation_all['Hourly_Ratio'] = hour_randomisation_all.Control / hour_randomisation_all.Experiment
hour_randomisation_all.loc[hour_randomisation_all.Hourly_Ratio.isnull(),['Hourly_Ratio']] = 0.0


plt.rc('xtick', labelsize=15) 
plt.rc('ytick', labelsize=15) 

fig, axs = plt.subplots(nrows=1,ncols=1,figsize=(8,5))

allocation_curve_hour = sns.lineplot(x="Hour_of_Day",
                                y="Hourly_Ratio",
                                markers="o",
                                markersize=10,
                                linewidth=2.5,
                                data=hour_randomisation_all)

axs.set_ylabel('Allocation Ratio',fontsize=16)
axs.set_xlabel('Hour of the Day',fontsize=16)
axs.set_yticks(np.arange(0, 4.2, step=.4))
axs.set_xticks(np.arange(0, 23, step=2))
axs.set_title("Randomisation Allocation By Hour of the Day",weight='bold').set_fontsize('18')
plt.show()
day_randomisation = learners_group.groupby(['Group','Day_Week']).User.count()
day_randomisation = day_randomisation.to_frame()
day_randomisation.reset_index(inplace=True)
day_randomisation_ctrl = day_randomisation.iloc[range(0,7)]
day_randomisation_ctrl.drop('Group',axis=1,inplace=True)
day_randomisation_ctrl.rename(columns={'User':'Control'},inplace=True)
day_randomisation_exp = day_randomisation.iloc[range(7,14)]
day_randomisation_exp.rename(columns={'User':'Experiment'},inplace=True)
day_randomisation_exp.drop('Group',axis=1,inplace=True)

day_randomisation_all = pd.merge(day_randomisation_ctrl,day_randomisation_exp,on='Day_Week',how='outer')
day_randomisation_all['Daily_Ratio'] = day_randomisation_all.Control / day_randomisation_all.Experiment
day_randomisation_all.loc[day_randomisation_all.Daily_Ratio.isnull(),['Daily_Ratio']] = 0.0

day_randomisation_all.Day_Week = pd.Categorical(day_randomisation_all.Day_Week.tolist(),
                                                categories=['Monday','Tuesday','Wednesday',                                                                       
                                                            'Thursday','Friday','Saturday','Sunday'])

day_randomisation_all.sort_values(by =['Day_Week'],inplace=True)

plt.rc('xtick', labelsize=15) 
plt.rc('ytick', labelsize=15) 

fig, axs = plt.subplots(nrows=1,ncols=1,figsize=(8,5))

allocation_curve_day = sns.lineplot(x="Day_Week",
                                y="Daily_Ratio",
                                markers="o",
                                markersize=10,
                                linewidth=2.5,
                                data=day_randomisation_all)

axs.set_ylabel('Allocation Ratio',fontsize=16)
axs.set_xlabel('Day of the Week',fontsize=16)
axs.set_yticks(np.arange(0.8, 2.2, step=.2))
axs.set_title("Randomisation Allocation By Day of the Week",weight='bold').set_fontsize('18')
plt.show()
month_randomisation = learners_group.groupby(['Group','Month_Year']).User.count()
month_randomisation = month_randomisation.to_frame()
month_randomisation.reset_index(inplace=True)

month_randomisation_ctrl = month_randomisation.iloc[range(0,6)]
month_randomisation_ctrl.drop('Group',axis=1,inplace=True)
month_randomisation_ctrl.rename(columns={'User':'Control'},inplace=True)
month_randomisation_exp = month_randomisation.iloc[range(6,12)]
month_randomisation_exp.rename(columns={'User':'Experiment'},inplace=True)
month_randomisation_exp.drop('Group',axis=1,inplace=True)

month_randomisation_all = pd.merge(month_randomisation_ctrl,month_randomisation_exp,on='Month_Year',how='outer')
month_randomisation_all['Monthly_Ratio'] = month_randomisation_all.Control / month_randomisation_all.Experiment
month_randomisation_all.loc[month_randomisation_all.Monthly_Ratio.isnull(),['Monthly_Ratio']] = 0.0

month_randomisation_all.Month_Year = pd.Categorical(month_randomisation_all.Month_Year.tolist(),
                                                categories=['February','March','April',                                                                       
                                                            'May','June','July'])

month_randomisation_all.sort_values(by =['Month_Year'],inplace=True)

plt.rc('xtick', labelsize=15) 
plt.rc('ytick', labelsize=15) 

fig, axs = plt.subplots(nrows=1,ncols=1,figsize=(8,5))

allocation_curve_day = sns.lineplot(x="Month_Year",
                                y="Monthly_Ratio",
                                markers="o",
                                markersize=10,
                                linewidth=2.5,
                                data=month_randomisation_all)

axs.set_ylabel('Allocation Ratio',fontsize=16)
axs.set_xlabel('Month of the Year',fontsize=16)
axs.set_yticks(np.arange(0.8, 2.2, step=.2))
axs.set_title("Randomisation Allocation By Month of the Year",weight='bold').set_fontsize('18')
plt.show()
#Spacing data

play_spacing =  play_data[['User','Session','Session_Complete']]
play_spacing = play_spacing.drop_duplicates(['User','Session','Session_Complete'])
session_numbers = play_spacing.groupby(['User']).agg({'Session':'count',
                                                     'Session_Complete':np.sum})
session_numbers.reset_index(inplace=True)
session_numbers = session_numbers.rename(columns={"Session": "No_Session", "Session_Complete": "No_Session_Complete"})
users_list = pd.merge(users_list,session_numbers,how='left',on=['User'])
users_list.to_csv(ROOT_DATA+'users.csv',index=False)

users_list.tail()
Regional_dist = users_list.Region[users_list.User.isin(play_data.User)].value_counts()
Regional_dist = Regional_dist.to_frame()
Regional_dist.reset_index(inplace=True)
Regional_dist.rename(columns={"index":"Sub-Regions","Region":"Count"},inplace=True)
Regional_dist.loc[Regional_dist['Sub-Regions']=='nan',['Sub-Regions']]="Missing"
Regional_dist['Percentage'] = round(Regional_dist.Count / Regional_dist.Count.sum(),4)*100
Regional_dist.sort_values(by=['Count'],ascending=False)
len(users_list.Region[users_list.User.isin(play_data.User)].tolist())
reached_endpoint = users_list[(users_list.No_Session_Complete > 1.0)]
reached_endpoint.StudyGroup.value_counts()<jupyter_output><empty_output><jupyter_text>Calculate scores for each completed session<jupyter_code>play_matched =  play_data[(play_data.Try==1)&(play_data.Session_Complete==1)&(play_data.Complete_Plays>1)]
session_ids  =  play_matched[['User','Session']]
session_ids = session_ids.drop_duplicates(['User','Session'])
session_ids['I'] = 1.0
session_ids['Cycle'] = session_ids.groupby(['User']).I.cumcount()+1
session_ids = session_ids.drop('I',axis=1)
norm_gain =  pd.merge(play_matched,session_ids,how='left',on=['User','Session']) 
norm_gain = norm_gain[norm_gain.Cycle < 3]

norm_gain = norm_gain.groupby(['User','Session','Question','Try','Cycle']).first()
norm_gain.reset_index(inplace=True)
norm_gain.tail()
play_data_count_feedback = play_data[(play_data.Complete_Plays >1) & ~(play_data.Correct==1)]

counter_session = play_data_count_feedback[['User','Session']]
counter_session =counter_session.drop_duplicates(['User','Session'])
counter_session['I'] =1
counter_session['Which_Cycle'] = counter_session.groupby(['User']).I.cumsum()
counter_session.drop('I',axis=1,inplace=True)
play_data_count_feedback = pd.merge(play_data_count_feedback,counter_session,how='left',on=['User','Session'])
play_data_count_feedback = play_data_count_feedback[play_data_count_feedback.Which_Cycle < 3]
play_data_count_feedback = pd.merge(play_data_count_feedback,users_list[['User','StudyGroup']],how='left',on='User')
play_data_count_feedback.Feedback.value_counts()
play_data_count_feedback.head()
experiment_sessions = play_data_count_feedback[['User','Session']].drop_duplicates(['User','Session'])
experiment_sessions.reset_index(inplace=True,drop=True)
experiment_sessions.tail()
pd.crosstab(play_data_count_feedback.StudyGroup,
            play_data_count_feedback.Feedback,margins=True)
pd.crosstab(play_data_count_feedback.StudyGroup,
            play_data_count_feedback.Feedback,margins=True,normalize=True)
len(norm_gain.User[norm_gain.Cycle==2].unique())
gap_data = play_data[['User','Session','Time']]
session_trackers = play_data[['User','Session','Session_Complete','Complete_Plays']]
session_trackers = session_trackers.drop_duplicates(['User','Session','Session_Complete','Complete_Plays'])
group_data = users_list[['User','StudyGroup']]
gap_data = (gap_data.groupby(['User','Session']).Time.sum()).to_frame()
gap_data.reset_index(inplace=True)
gap_data['Time_Difference'] = gap_data.groupby('User').Session.transform(lambda x: ((x -x.shift()).dt.total_seconds()))
gap_data['Gap']=np.nan

def cumilate_gap(user_data):
    user_data['Gap'] = user_data.Time_Difference + user_data.Time.shift()
    return(user_data)
    
gap_data = gap_data.groupby('User').apply(cumilate_gap)
gap_data.drop(['Time','Time_Difference'],axis=1,inplace=True)
gap_data.Gap = gap_data.Gap/60.0

gap_data['Gap_Type'] = 'None'
gap_data.loc[gap_data.Gap <= 60.0,['Gap_Type']] = '<= 1 Hour'
gap_data.loc[(gap_data.Gap > 60.0) & (gap_data.Gap <= 1440.0),['Gap_Type']] = '<= 1 Day'
gap_data.loc[(gap_data.Gap > 1440.0) & (gap_data.Gap <= 10080.0),['Gap_Type']] = '<= 1 Week'
gap_data.loc[(gap_data.Gap > 10080.0) & (gap_data.Gap <=  40320.0),['Gap_Type']] = '<= 1 Month'
gap_data.loc[(gap_data.Gap > 40320.0),['Gap_Type']] = '> 1 Month'


gap_data.loc[gap_data.Gap.isnull(),['Gap']]=0.01
gap_data.Gap = np.log(gap_data.Gap)

secondary_analysis_play_data = play_data[['User','Session','Question','Try','Time','Feedback','Correct']]
secondary_analysis_play_data['I'] = 1
secondary_analysis_play_data['Opportunity'] = secondary_analysis_play_data.groupby(['User','Question']).I.cumcount()+1
secondary_analysis_play_data.drop(['I'],axis=1,inplace=True)
secondary_analysis_play_data = pd.merge(secondary_analysis_play_data,gap_data,how='left',on=['User','Session'])
secondary_analysis_play_data = pd.merge(secondary_analysis_play_data,group_data,how='left',on=['User'])
secondary_analysis_play_data.StudyGroup = secondary_analysis_play_data.StudyGroup.astype(str)
secondary_analysis_play_data.loc[secondary_analysis_play_data.StudyGroup=='2',['StudyGroup']] = 'Experiment'
secondary_analysis_play_data.loc[secondary_analysis_play_data.StudyGroup=='1',['StudyGroup']] = 'Control'
secondary_analysis_play_data.rename(columns={'StudyGroup':'Group'},inplace=True)

session_ids  =  play_data[['User','Session']]
session_ids = session_ids.drop_duplicates(['User','Session'])
session_ids['I'] = 1.0
session_ids['Cycle'] = session_ids.groupby(['User']).I.cumcount()+1
session_ids.drop('I',axis=1,inplace=True)
secondary_analysis_play_data = pd.merge(secondary_analysis_play_data,session_ids,how='left',on=['User','Session'])
secondary_analysis_play_data = pd.merge(secondary_analysis_play_data,session_trackers,how='left',on=['User','Session'])

srl_data_mutinom = pd.read_csv('D:\DPhil - University of Oxford\Reports\SRL\multinom.csv')
srl_data_mutinom = srl_data_mutinom[['User','SRL']]
srl_data_mutinom = srl_data_mutinom[~(srl_data_mutinom.User.isnull())]

srl_data_mutinom.SRL = srl_data_mutinom.SRL.astype(str)

srl_data_mutinom.loc[srl_data_mutinom.SRL=='1',['SRL']] = 'Low SRL profile'
srl_data_mutinom.loc[srl_data_mutinom.SRL=='2',['SRL']] = 'Average SRL profile'
srl_data_mutinom.loc[srl_data_mutinom.SRL=='3',['SRL']] = 'Above Average SRL profile'
srl_data_mutinom.loc[srl_data_mutinom.SRL=='4',['SRL']] = 'High SRL profile'

secondary_analysis_play_data = pd.merge(secondary_analysis_play_data,
                                        srl_data_mutinom,how='left',on=['User'])

secondary_analysis_play_data.head()
secondary_analysis_play_data.User.nunique()<jupyter_output><empty_output><jupyter_text>Feedback by Experiment Group<jupyter_code>secondary_analysis_play_data['Hint'] = 1.0
secondary_analysis_play_data['Attempts'] = 1.0
secondary_analysis_play_data.loc[secondary_analysis_play_data.Correct==1,['Hint']]= 0.0
secondary_analysis_play_data.groupby(['Group']).agg({'Time':['mean','std']})
from scipy import stats
np.round(stats.ttest_ind(secondary_analysis_play_data.Time[secondary_analysis_play_data.Group=='Control'],
         secondary_analysis_play_data.Time[secondary_analysis_play_data.Group=='Experiment'])[1],3)
hint_ratio_table=secondary_analysis_play_data.groupby(['User','Session','Group']).agg(
    {'Hint':'sum',
     'Attempts':'sum'})
hint_ratio_table.reset_index(inplace=True)
hint_ratio_table['Ratio'] = np.round(hint_ratio_table.Hint / hint_ratio_table.Attempts,3)
hint_ratio_table.head()
hint_ratio_table.groupby(['Group']).agg(
    {'Hint':['mean','std']})
np.round(stats.ttest_ind(hint_ratio_table.Hint[hint_ratio_table.Group=='Control'],
         hint_ratio_table.Hint[hint_ratio_table.Group=='Experiment'])[1],3)
secondary_analysis_play_data[secondary_analysis_play_data.Correct==0].groupby(['Group']).agg(
    {'Time':'std'})
pd.crosstab(secondary_analysis_play_data.Group[secondary_analysis_play_data.Correct==0],
            secondary_analysis_play_data.Feedback[secondary_analysis_play_data.Correct==0],margins=True)
secondary_analysis_play_data.User.nunique()
pd.crosstab(secondary_analysis_play_data.Group[secondary_analysis_play_data.Correct==0],
            secondary_analysis_play_data.Feedback[secondary_analysis_play_data.Correct==0],normalize=True,margins=True)
len(secondary_analysis_play_data.User[secondary_analysis_play_data.Complete_Plays > 1].unique())
users_in_experiment = secondary_analysis_play_data.User[secondary_analysis_play_data.Complete_Plays > 1].unique()
secondary_analysis_play_data_blah = secondary_analysis_play_data[secondary_analysis_play_data.User.isin(users_in_experiment)]
secondary_analysis_play_data_blah.groupby(['Group']).agg({'Time':['mean','std']})
np.round(stats.ttest_ind(secondary_analysis_play_data_blah.Time[
    secondary_analysis_play_data_blah.Group=='Control'],
         secondary_analysis_play_data_blah.Time[secondary_analysis_play_data_blah.Group=='Experiment'])[1],3)
hint_ratio_table=secondary_analysis_play_data_blah.groupby(['User','Session','Group']).agg(
    {'Hint':'sum',
     'Attempts':'sum'})
hint_ratio_table.reset_index(inplace=True)
hint_ratio_table['Ratio'] = np.round(hint_ratio_table.Hint / hint_ratio_table.Attempts,3)
hint_ratio_table.groupby(['Group']).agg(
    {'Hint':['mean','std']})
np.round(stats.ttest_ind(hint_ratio_table.Hint[hint_ratio_table.Group=='Control'],
         hint_ratio_table.Hint[hint_ratio_table.Group=='Experiment'])[1],3)<jupyter_output><empty_output><jupyter_text>Prepare data for experiment + secondary analysis<jupyter_code>secondary_analysis_curve = secondary_analysis_play_data[['User','Session','Session_Complete']]
secondary_analysis_curve = secondary_analysis_curve.drop_duplicates(['User','Session','Session_Complete'])
secondary_analysis_curve = secondary_analysis_curve[secondary_analysis_curve.Session_Complete==1]
secondary_analysis_curve['I'] = 1
secondary_analysis_curve['Cycle_Complete'] = secondary_analysis_curve.groupby(['User']).I.cumcount()+1
secondary_analysis_curve.drop(['I','Session_Complete'],axis=1,inplace=True)
secondary_analysis_curve.reset_index(inplace=True,drop=True)
secondary_analysis_curve.tail()
norm_gain.head()
secondary_analysis_play_data.head()
secondary_analysis_lc = pd.merge(play_data,secondary_analysis_curve,how='left',on=['User','Session'])
secondary_analysis_lc['Feedback_Given'] = 0.0
secondary_analysis_lc.loc[secondary_analysis_lc.Feedback.astype(int) > 0, ['Feedback_Given']]=1.0


user_session_summary = secondary_analysis_lc.groupby(['User','Session']).agg({'Time':'sum',
                                                       'Feedback_Given':'sum',
                                                       'Try':'count'})

user_session_summary.reset_index(inplace=True)
user_session_summary.rename(columns={'Feedback_Given':'Feedback_Count',
                                    'Try':'Try_Count'},inplace=True)


secondary_analysis_lc = secondary_analysis_lc[secondary_analysis_lc.Try==1]
secondary_analysis_lc = secondary_analysis_lc[~(secondary_analysis_lc.Cycle_Complete.isnull())]
secondary_analysis_lc.drop(['Try','Quiz_Attempted','Session_Complete'],axis=1,inplace=True)

secondary_performance = secondary_analysis_lc[['User','Session','Cycle_Complete','Correct']]

#secondary_analysis_lc.to_csv('D:/DPhil - University of Oxford/Data/Norm_all.csv',index=False)
#secondary_analysis_lc.head()

secondary_performance = secondary_performance.groupby(['User','Session','Cycle_Complete']).Correct.sum()
secondary_performance = secondary_performance.to_frame()
secondary_performance.reset_index(inplace=True)

secondary_performance['Previous_Score'] = secondary_performance.groupby('User').Correct.shift()
secondary_performance.rename(columns={'Correct':'Score'},inplace=True)
#secondary_performance = secondary_performance[~secondary_performance.Previous_Score.isnull()]
secondary_performance['Gain'] = np.nan
#cumilative_plays['Score'] = np.nan

def calc_norm_gain(pre,post):
    if(post > pre):
        return ((post-pre)/(10.0-pre))
    elif(pre==post):
        return (0.0)
    elif(post < pre):
        return((post-pre)/pre)
    else:
        return None

for index,row in secondary_performance.iterrows():
    user,session = row['User'],row['Session']
    if ~(pd.isnull(row['Previous_Score'])):
        gain=calc_norm_gain(float(row['Previous_Score']),float(row['Score']))
        secondary_performance.loc[(secondary_performance.User==user)&(secondary_performance.Session==session),
                                  ['Gain']]=gain
#secondary_performance.drop('Previous_Score',axis=1,inplace=True)
return_students = secondary_analysis_play_data[['User','Session','Gap','Gap_Type']]
return_students = return_students.drop_duplicates(['User','Session','Gap','Gap_Type'])
return_students.rename(columns={'Gap_Type':'Spacing'},inplace=True)

demographic = users_list[['User','Cadre','Level','Age','Experience','StudyGroup']]
demographic.StudyGroup = demographic.StudyGroup.astype(str)
demographic.loc[demographic.StudyGroup=='1',['StudyGroup']] = 'Control'
demographic.loc[demographic.StudyGroup=='2',['StudyGroup']] = 'Experiment'
demographic.rename(columns={'StudyGroup':'Group'},inplace=True)

secondary_performance = pd.merge(secondary_performance,user_session_summary,how='left',on=['User','Session'])
secondary_performance = pd.merge(secondary_performance,srl_data_mutinom,how='left',on='User')
secondary_performance = pd.merge(secondary_performance,return_students,how='left',on=['User','Session'])
secondary_performance = pd.merge(secondary_performance,demographic,how='left',on=['User'])

etat_users = users_list[['User','ETAT']]
etat_users = etat_users.drop_duplicates(['User','ETAT'])
secondary_performance = pd.merge(secondary_performance,etat_users,how='left',on=['User'])
secondary_performance.ETAT = secondary_performance.ETAT.astype(str)
secondary_performance.loc[secondary_performance.ETAT=='False',['ETAT']] = 'No'
secondary_performance.loc[secondary_performance.ETAT=='True',['ETAT']] = 'Yes'

secondary_performance.head()
#from IPython.display import Javascript
#display(Javascript('IPython.notebook.execute_cells_above()'))
protocol_users = secondary_analysis_play_data.User[secondary_analysis_play_data.Cycle>1].unique().tolist()
secondary_analysis_play_data[secondary_analysis_play_data.User.isin(protocol_users) & secondary_analysis_play_data.Cycle==2]
print(len(protocol_users))
norm_data = secondary_analysis_play_data[secondary_analysis_play_data.User.isin(protocol_users)]
##Spacing normalised gain over time
play_matched =  secondary_analysis_play_data[(secondary_analysis_play_data.Try==1)&
                                             (secondary_analysis_play_data.Session_Complete==1)&
                                             (secondary_analysis_play_data.Complete_Plays > 0)]
inter_gain_scores = play_matched.groupby(['User','Session']).Correct.agg('sum')
inter_gain_scores = inter_gain_scores.to_frame()
inter_gain_scores.reset_index(inplace=True)
inter_gain_scores['Score'] = np.round(inter_gain_scores.Correct/10,4)*100
inter_gain_scores.loc[inter_gain_scores.Score > 100.0,['Score']] = 100.0
users_group = secondary_analysis_play_data[['User','Group','Session','Gap_Type']]
users_group = users_group.drop_duplicates(['User','Group','Session','Gap_Type'])
inter_gain_scores = pd.merge(inter_gain_scores,users_group,how='left',on=['User','Session'])

fix_cycle  =  inter_gain_scores[['User','Session']]
fix_cycle = fix_cycle.drop_duplicates(['User','Session'])
fix_cycle['I'] = 1.0
fix_cycle['Cycle'] = fix_cycle.groupby(['User']).I.cumcount()+1
fix_cycle.drop('I',axis=1,inplace=True)
inter_gain_scores = pd.merge(inter_gain_scores,fix_cycle,how='left',on=['User','Session'])

inter_gain_scores.head()
pd.crosstab(inter_gain_scores[inter_gain_scores.Cycle==2].Group,
            inter_gain_scores.Gap_Type,margins=True)
pd.crosstab(inter_gain_scores[inter_gain_scores.Cycle==2].Group,
            inter_gain_scores.Gap_Type,margins=True,normalize=True)
secondary_analysis_play_data.head()
def calc_norm_gain(pre,post):
    if(post > pre):
        return ((post-pre)/(100.0-pre))
    elif(pre==post):
        return (0.0)
    elif(post < pre):
        return((post-pre)/pre)
    else:
        return None

def sort_gains(user_data):
    this_user_data = user_data.copy()
    this_user_data.reset_index()
    scores = this_user_data.Score.tolist()
    end = int(this_user_data.shape[0])-1
    gains=[None]*end
    for i in range(0,end):
        next_score_id = i+1
        i_gain = calc_norm_gain(scores[i],scores[next_score_id])
        gains[i]=np.round(i_gain,4)
    return(gains)
cumilative_plays = play_data[['User','Session']]
cumilative_plays = cumilative_plays.drop_duplicates()
cumilative_plays.reset_index(inplace=True,drop=True)


cumilative_plays['Time_Spent'] = np.nan
cumilative_plays['Tries'] = np.nan
cumilative_plays['Questions_Attempted'] = np.nan

for index,row in cumilative_plays.iterrows():
    user,session = row['User'], row['Session']
    Questions_attempted = play_data.Question[(play_data.User==user)&(play_data.Session==session)].nunique()
    Tries = play_data.Question[(play_data.User==user)&(play_data.Session==session)].count()
    Time_Spent = round(play_data.Time[(play_data.User==user)&(play_data.Session==session)].sum(),2)
    cumilative_plays.loc[index,['Questions_Attempted']] = Questions_attempted
    cumilative_plays.loc[index,['Tries']] = Tries
    cumilative_plays.loc[index,['Time_Spent']] = Time_Spent

cumilative_plays['I'] = 1
Cumilative_Sessions = cumilative_plays.groupby(['User','Session']).sum().groupby(level=[0]).I.cumsum()
Cumilative_Sessions = Cumilative_Sessions.to_frame()
Cumilative_Sessions.reset_index(inplace=True)
Cumilative_Sessions.rename(columns={"I":"Cumilative_Sessions"},inplace=True)
cumilative_plays.drop(['I'],axis=1,inplace=True)
cumilative_plays = pd.merge(cumilative_plays,Cumilative_Sessions,how='left',on=['User','Session'])

cumilative_plays['I'] = np.nan
cumilative_plays.loc[cumilative_plays.Questions_Attempted==10,['I']] = 1
Cumilative_Complete_Sessions = cumilative_plays.groupby(['User','Session']).sum().groupby(level=[0]).I.cumsum()
Cumilative_Complete_Sessions = Cumilative_Complete_Sessions.to_frame()
Cumilative_Complete_Sessions.reset_index(inplace=True)
Cumilative_Complete_Sessions.rename(columns={"I":"Cumilative_Complete_Sessions"},inplace=True)
cumilative_plays.drop(['I'],axis=1,inplace=True)
cumilative_plays = pd.merge(cumilative_plays,Cumilative_Complete_Sessions,how='left',on=['User','Session'])
cumilative_plays.Cumilative_Complete_Sessions = cumilative_plays.Cumilative_Complete_Sessions.astype(int)
cumilative_plays.Questions_Attempted = cumilative_plays.Questions_Attempted.astype(int)

cumilative_plays_gains = cumilative_plays[cumilative_plays.Questions_Attempted==10]
#cumilative_plays_gains = cumilative_plays_gains[['User','Session']]
cumilative_plays_gains['Score']=np.nan
for index,row in cumilative_plays_gains.iterrows():
    user,session = row['User'],row['Session']
    score = play_data.Correct[(play_data.User==user)&(play_data.Session==session)&(play_data.Try==1)].sum()
    cumilative_plays_gains.loc[(cumilative_plays.User==user)&(cumilative_plays.Session==session),['Score']]=(score/10)*100
    
cumilative_plays_gains['Previous_Score'] = cumilative_plays_gains.groupby('User').Score.shift()
calc_learner_gains = cumilative_plays_gains[~cumilative_plays_gains.Previous_Score.isnull()]
cumilative_plays['Gain'] = np.nan
cumilative_plays['Score'] = np.nan
for index,row in cumilative_plays_gains.iterrows():
    user,session = row['User'],row['Session']
    gain=calc_norm_gain(float(row['Previous_Score']),float(row['Score']))
    cumilative_plays.loc[(cumilative_plays.User==user)&(cumilative_plays.Session==session),['Gain']]=gain
    cumilative_plays.loc[(cumilative_plays.User==user)&(cumilative_plays.Session==session),['Score']]=float(row['Score'])

cumilative_plays = cumilative_plays[~cumilative_plays.Gain.isnull()]
cumilative_plays['Session_Attempt_Rate'] = round(cumilative_plays.Cumilative_Complete_Sessions/cumilative_plays.Cumilative_Sessions,3)
cumilative_plays['Attempt_Accuracy_Rate'] = round(10/cumilative_plays.Tries,3)
cumilative_plays.Gain = round(cumilative_plays.Gain,3)

cumilative_plays['Experiment']=0
cumilative_plays['ETAT']=0
for index,row in cumilative_plays.iterrows():
    user = row['User']
    study_group = users_list.StudyGroup[users_list.User==user].tolist()[0]
    etat = users_list.ETAT[users_list.User==user].tolist()[0]
    if study_group == 2:
        cumilative_plays.loc[index,['Experiment']]=1   
    if etat:
        cumilative_plays.loc[index,['ETAT']]=1 
cumilative_plays.drop(['Questions_Attempted','Session'],axis=1,inplace=True)
cumilative_plays.reset_index(drop=True,inplace=True)
cumilative_plays.head()
cumilative_plays = play_data[['User','Session']]
cumilative_plays = cumilative_plays.drop_duplicates()
cumilative_plays.reset_index(inplace=True,drop=True)


cumilative_plays['Time_Spent'] = np.nan
cumilative_plays['Tries'] = np.nan
cumilative_plays['Questions_Attempted'] = np.nan

for index,row in cumilative_plays.iterrows():
    user,session = row['User'], row['Session']
    Questions_attempted = play_data.Question[(play_data.User==user)&(play_data.Session==session)].nunique()
    Tries = play_data.Question[(play_data.User==user)&(play_data.Session==session)].count()
    Time_Spent = round(play_data.Time[(play_data.User==user)&(play_data.Session==session)].sum(),2)
    cumilative_plays.loc[index,['Questions_Attempted']] = Questions_attempted
    cumilative_plays.loc[index,['Tries']] = Tries
    cumilative_plays.loc[index,['Time_Spent']] = Time_Spent

cumilative_plays['I'] = 1
Cumilative_Sessions = cumilative_plays.groupby(['User','Session']).sum().groupby(level=[0]).I.cumsum()
Cumilative_Sessions = Cumilative_Sessions.to_frame()
Cumilative_Sessions.reset_index(inplace=True)
Cumilative_Sessions.rename(columns={"I":"Cumilative_Sessions"},inplace=True)
cumilative_plays.drop(['I'],axis=1,inplace=True)
cumilative_plays = pd.merge(cumilative_plays,Cumilative_Sessions,how='left',on=['User','Session'])

cumilative_plays['I'] = np.nan
cumilative_plays.loc[cumilative_plays.Questions_Attempted==10,['I']] = 1
Cumilative_Complete_Sessions = cumilative_plays.groupby(['User','Session']).sum().groupby(level=[0]).I.cumsum()
Cumilative_Complete_Sessions = Cumilative_Complete_Sessions.to_frame()
Cumilative_Complete_Sessions.reset_index(inplace=True)
Cumilative_Complete_Sessions.rename(columns={"I":"Cumilative_Complete_Sessions"},inplace=True)
cumilative_plays.drop(['I'],axis=1,inplace=True)
cumilative_plays = pd.merge(cumilative_plays,Cumilative_Complete_Sessions,how='left',on=['User','Session'])
cumilative_plays.Cumilative_Complete_Sessions = cumilative_plays.Cumilative_Complete_Sessions.astype(int)
cumilative_plays.Questions_Attempted = cumilative_plays.Questions_Attempted.astype(int)
cumilative_plays = cumilative_plays[cumilative_plays.Questions_Attempted == 10]

cumilative_plays['Score']=np.nan
cumilative_plays['Experiment']=0
cumilative_plays['ETAT']=0

for index,row in cumilative_plays_gains.iterrows():
    user,session = row['User'],row['Session']
    
    study_group = users_list.StudyGroup[users_list.User==user].tolist()[0]
    etat = users_list.ETAT[users_list.User==user].tolist()[0]
    if study_group == 2:
        cumilative_plays.loc[index,['Experiment']]=1   
    if etat:
        cumilative_plays.loc[index,['ETAT']]=1 
    score = play_data.Correct[(play_data.User==user)&(play_data.Session==session)&(play_data.Try==1)].sum()
    cumilative_plays.loc[(cumilative_plays.User==user)&(cumilative_plays.Session==session),['Score']]=(score/10)*100

cumilative_plays['Completion_Rate']=round(cumilative_plays.Cumilative_Complete_Sessions/cumilative_plays.Cumilative_Sessions,4)
cumilative_plays['Accuracy_Rate']=round(10/cumilative_plays.Tries,4)
cumilative_plays.drop(['Session','Tries','Questions_Attempted','Cumilative_Complete_Sessions'],axis=1,inplace=True)
cumilative_plays.reset_index(drop=True,inplace=True)
##Spacing normalised gain over time
play_matched =  play_data[(play_data.Session_Complete==1)&(play_data.Complete_Plays>1)]

session_time  =  play_matched[['User','Session','Time']]
session_time_gains = session_time.groupby(['User','Session']).Time.sum().to_frame()
session_time_gains.reset_index(inplace=True)
session_time_gains['I'] = 1.0
session_time_gains['Cycle'] = session_time_gains.groupby(['User']).I.cumcount()+1
session_time_gains = session_time_gains.drop('I',axis=1)
session_time_gains = session_time_gains[session_time_gains.Cycle < 6]
session_time_gains.tail()
time_gains = session_time_gains.pivot_table('Time',['User'],'Cycle')
time_gains = time_gains.reset_index(drop=True)
time_gains.tail()
time_gains_len = time_gains.shape[1]
data = [None] * time_gains_len

for i in range(1,(time_gains_len+1)):
    assign_idx = i -1
    cmd="trace"+str(i)+"=go.Box(x=['"+str(i)+"']*len(time_gains["+str(i)+"].dropna()),y=time_gains["+str(i)+"].dropna(),name='"+str(i)+"')"
    exec(cmd)
    cmd="data["+str(assign_idx)+"]=trace"+str(i)
    exec(cmd)

layout = {"title": "Time utilisation by sessions", 
          "xaxis": {"title": "Successive learning sessions"}, 
          "yaxis": {"title": "Session Length (Seconds)"},
          "font" :{"family":"Corbel","size":18,"color":"#7f7f7f"},
          "showlegend" : False
         }

fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='basic_dot-plot')
##Spacing normalised gain over time
play_matched =  play_data[(play_data.Try==1)&(play_data.Session_Complete==1)&(play_data.Complete_Plays>1)]
session_ids  =  play_matched[['User','Session']]
session_ids = session_ids.drop_duplicates(['User','Session'])
session_ids = session_ids.drop_duplicates(['User','Session'])
session_ids['I'] = 1.0
session_ids['Cycle'] = session_ids.groupby(['User']).I.cumcount()+1
session_ids = session_ids.drop('I',axis=1)
session_ids.tail()
def sort_time_gains(user_data):
    this_user_data = user_data.copy()
    this_user_data.reset_index()
    scores = this_user_data.Session.tolist()
    end = int(this_user_data.shape[0])-1
    gains=[None]*end
    for i in range(0,end):
        next_score_id = i+1
        pre,post = pd.to_datetime(scores[i]),pd.to_datetime(scores[next_score_id])   
        i_gain = np.ceil(((post - pre).total_seconds())/60)
        i_gain = np.where(i_gain > 10080.0, 10080.0, i_gain)
        gains[i]=i_gain
    return(gains)
    
all_gains = session_ids.groupby(['User']).apply(sort_time_gains)
all_gains = all_gains.to_frame()
all_gains.reset_index(inplace=True)
all_gains=all_gains.rename(columns={0:'Time_Diff'})
all_gains_dcast = pd.DataFrame(all_gains.Time_Diff.values.tolist(), index= all_gains.User)
all_gains_dcast = all_gains_dcast.drop([5,6,7,8,9],axis=1)
all_gains_dcast.tail()
gains_len = all_gains_dcast.shape[1]
data = [None] * gains_len
for i in range(0,gains_len):
    lbl = i+1
    cmd="trace"+str(lbl)+"=go.Box(x=['"+str(lbl)+"']*len(all_gains_dcast["+str(i)+"].dropna()),y=all_gains_dcast["+str(i)+"].dropna(),name='"+str(lbl)+"')"
    exec(cmd)
    cmd="data["+str(i)+"]=trace"+str(lbl)
    exec(cmd)

layout = {"title": "Spacing of Learning Sessions", 
          "xaxis": {"title": "Successive comparisons" }, 
          "yaxis": {"title": "Time Between Sessions"},
          "font" :{"family":"Corbel","size":18,"color":"#7f7f7f"},
          "showlegend" : False,
         }

fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='basic_dot-plot')
play_all = len(play_data.User.dropna().unique())
play_data_complete = len(play_data.User[play_data.Complete_Plays>0].dropna().unique())
play_data_repeated = len(play_data.User[play_data.Complete_Plays>1].dropna().unique())

print("Number of HWs who started a scenario so far: " + str(play_all))
print("Number of HWs who completed a scenario so far: " + str(play_data_complete))
print("Number of HWs who completed a scenario multiple times so far: " + str(play_data_repeated))

users_to_email = play_data.User[play_data.Complete_Plays < 2].dropna().unique()
email_list = users_list.Email[users_list.User.isin(users_to_email) & (users_list.Country=='ke')].dropna()
email_list = [email for email in email_list if not email=='Empty']

mailing_list = pd.DataFrame({'Email':pd.Series(email_list)})
mailing_list['Count'] = 1.0
recruitment = [go.Bar(
    x = ['Users Started \nSession','Users Completed \nSingle Session','Users Completed \nMultiple Sessions'],
    y = [play_all,play_data_complete,play_data_repeated],
    text = [play_all,play_data_complete,play_data_repeated],
    textposition = 'auto',
    textfont=dict(
            family='Corbel',
            size=18
    ),
    opacity = 0.75
)]

layout = go.Layout(
    title='LIFE recruitment progress',
    xaxis=dict(title='Click Through Types'),
    yaxis=dict(title='Click Through Counts'),    
    font=dict(family='Corbel', size=18, color='#7f7f7f'),
)

py.iplot(go.Figure(data=recruitment,layout=layout), filename='recruit-track')
srl_eligible=play_data.User[play_data.Complete_Plays>1]
study_participants = users_list[users_list.User.isin(srl_eligible)]
summary_experiment = study_participants.groupby(['StudyGroup']).User.nunique()
summary_experiment = summary_experiment.to_frame()
summary_experiment.reset_index(inplace=True)
summary_experiment
users_recruited = users_list[users_list.User.isin(play_data.User)]
users_recruited = users_recruited[['User','Session','ETAT','StudyGroup','No_Session','No_Session_Complete']]
users_recruited.rename(columns={'StudyGroup':'Group','No_Session':'Sessions_Started',
                                'No_Session_Complete':'Sessions_Completed'},inplace=True)
users_recruited.Group = users_recruited.Group.astype(str)
users_recruited.loc[users_recruited.Group=='1',['Group']] = 'Control'
users_recruited.loc[users_recruited.Group=='2',['Group']] = 'Experiment'
users_recruited.head()
play_data_perf = play_data[play_data.User.isin(users_recruited.User) & (play_data.Try==1)]
recruit_stats_perf = play_data_perf.groupby(['User','Session']).agg({
    'Question' : ['nunique'],
    'Correct' : ['sum']
})
recruit_stats_perf.reset_index(inplace=True)
recruit_stats_perf.columns = recruit_stats_perf.columns.droplevel(1)
recruit_stats_perf['Performance'] = np.round((recruit_stats_perf.Correct / recruit_stats_perf.Question)*100,2)
recruit_stats_perf = recruit_stats_perf.groupby('User').Performance.mean()
recruit_stats_perf = recruit_stats_perf.to_frame()
recruit_stats_perf.reset_index(inplace=True)
recruit_stats_perf.Performance = np.round(recruit_stats_perf.Performance,2)
recruit_stats_perf.head()
play_data_session = play_data[play_data.User.isin(users_recruited.User)]
recruit_stats = play_data_session.groupby(['User','Session']).agg({
    'Time' : ['sum'],
    'Question' : ['nunique']
})
recruit_stats.reset_index(inplace=True)
recruit_stats.columns = recruit_stats.columns.droplevel(1)
recruit_stats = recruit_stats.groupby('User').agg({'Time': ['mean'], 'Question' : ['mean'] })
recruit_stats.reset_index(inplace=True)
recruit_stats.columns = recruit_stats.columns.droplevel(1)
recruit_stats.Question = np.ceil(recruit_stats.Question)
recruit_stats.Question = recruit_stats.Question.astype(int)

recruit_stats.head()
users_recruited = pd.merge(users_recruited, recruit_stats, on=['User'], how='left')
users_recruited = pd.merge(users_recruited, recruit_stats_perf, on=['User'], how='left')
users_recruited.head()
#from IPython.display import Javascript
#display(Javascript('IPython.notebook.execute_cells_above()'))<jupyter_output><empty_output><jupyter_text>Get feedback use data<jupyter_code>neonate_bkt = db.child("resus").child("bkt").get()
bkt_data = pd.DataFrame()
for bkt_node in neonate_bkt.each():
    user_id=bkt_node.key()    
    for session_id,feedback_info in bkt_node.val().items():
        session = None
        try:
            session = datetime.strptime(session_id, '%b %d, %Y, %I:%M:%S %p')
            for feed_id,feed_data in feedback_info.items():
                stats = feed_data.split(',')
                stats[0]=stats[0].replace("Question","")
                row_cols = ["User","Session","Question","BKT","Probability"]
                row_vals=[user_id,session]
                row_vals.extend(stats)
                skill_row = pd.DataFrame.from_records([row_vals],columns=row_cols)
                bkt_data = pd.concat([bkt_data,skill_row])
        except:
            continue
        
bkt_data.BKT=bkt_data.BKT.str.capitalize()
bkt_data.Question=bkt_data.Question.astype(int)
bkt_data = bkt_data.loc[bkt_data.User.isin(play_data.User)]

bkt_data.to_csv(ROOT_DATA+'BKT.csv',index=False)
                
bkt_data.tail()
bkt_data_learn =  bkt_data[bkt_data.BKT=='Learn']
bkt_data_learn['Session_Use'] = bkt_data_learn.groupby(['User','Question']).Session.transform('max')
bkt_data_learn =  bkt_data_learn[bkt_data_learn.Session==bkt_data_learn.Session_Use]
bkt_data_learn_latest = bkt_data_learn.groupby(['User','Question']).Probability.last()
bkt_data_learn_latest = bkt_data_learn_latest.to_frame()
bkt_data_learn_latest.reset_index(inplace=True)
bkt_data_learn_latest.tail()<jupyter_output><empty_output><jupyter_text>Get SRL data<jupyter_code>neonate_srl = db.child("resus").child("srl").get()
srl_data = pd.DataFrame()
for srl_node in neonate_srl.each():
    user_id=srl_node.key()
    if(isinstance(srl_node.val(),dict)):                  
        for session_id, srl_info in srl_node.val().items():
            session = None
            try:
                session = datetime.strptime(session_id,'%b %d, %Y, %I:%M:%S %p')
            except:
                continue
            items_idx = list(range(1,21))
            items_idx = list(map(str, items_idx))
            items_idx=['Q' + idx for idx in items_idx]
            row_cols = ["User","Session"]
            row_cols.extend(items_idx)
            row_vals=[user_id,session]
            row_vals.extend(srl_info)
            if len(row_vals)==22:
                srl_row = pd.DataFrame.from_records([row_vals],columns=row_cols)
                srl_data = pd.concat([srl_data,srl_row])

srl_data=srl_data.sort_values(by=['Session'],ascending=[True])
srl_data = srl_data.loc[srl_data.User.isin(srl_play_data.User)]

srl_data = srl_data[srl_data.Session < '2019-08-01 00:00:01']
srl_data = srl_data[srl_data.Session > '2019-02-06 23:59:59']
srl_data = srl_data.reset_index(drop=True) 

srl_user_life_app = srl_data.User.dropna().unique().tolist()
srl_data.tail()
srl_data.groupby('User').first().shape
user_got_to_two = secondary_performance.User[secondary_performance.Cycle_Complete < 3.0].unique().tolist()
user_background = users_list[users_list.User.isin(user_got_to_two)]
user_background.StudyGroup.value_counts()
srl_data_clean = srl_data.groupby('User').first()
srl_data_clean = srl_data_clean.drop('Session',axis=1)
users_mplus = users_list[users_list.User.isin(srl_data_clean.index)]
users_mplus.drop(['ConsentGiven','Country','ETAT','Email','Institution',
                  'Region',
                  'Session'],axis=1,inplace=True)
users_mplus.drop(['StudyGroup','No_Session','No_Session_Complete'],axis=1,inplace=True)
users_mplus['Age_Class']=''
users_mplus.loc[users_mplus.Age.isnull(),['Age']]=0
users_mplus.Age = users_mplus.Age.astype(str)
users_mplus.Age = users_mplus.Age.str[:2]
users_mplus.Age = users_mplus.Age.astype(int)
users_mplus.loc[users_mplus.Age.between(18,24),['Age_Class']] ='18-24'
users_mplus.loc[users_mplus.Age.between(25,34),['Age_Class']] ='25-34'
users_mplus.loc[users_mplus.Age.between(35,44),['Age_Class']] ='35-44'
users_mplus.loc[users_mplus.Age.between(45,54),['Age_Class']] ='45-54'
users_mplus.loc[users_mplus.Age.between(55,64),['Age_Class']] ='55-64'
users_mplus.loc[users_mplus.Age > 65,['Age_Class']] = '65+'
users_mplus.drop('Age',axis=1,inplace=True)
users_mplus.rename(columns={'Age_Class':'Age'},inplace=True)
users_mplus = users_mplus[['User','Cadre','Level','Age','Experience']]
users_mplus.tail()
srl_comb = srl_data_clean.copy()
srl_comb.reset_index(inplace=True)
srl_data_firebase =  pd.merge(users_mplus,srl_comb,how='left',on=['User']) 
srl_data_firebase.loc[srl_data_firebase.Level=='General OfficerStudentIntern',['Level']]='Student'
srl_data_firebase.tail()
srl_data_form = pd.read_csv(ROOT_DATA+'LIFE_SRL_Survey.csv')
srl_data_form.drop(['Timestamp','Which hospital/training centre are you affiliated with?','What is your sex?'],axis=1,inplace=True)
srl_data_form.rename(columns={
                            "What is your age (in years)":"Age",
                              "What is your clinical cadre?":"Cadre",
                              "What is your current status of practice?":"Level",
                              "What is your experience level in years?":"Experience",
                             "I had personal goals for the LIFE training scenario":"Q1",
                             "I had realistic performance targets for LIFE training scenario":"Q2",
                             "Goals helped me manage my learning through LIFE":"Q3",
                             "When planning  learning through LIFE, I adapted strategies that have worked in the previous round":"Q4",
                             "I considered alternative options not provided in LIFE which might be better solutions":"Q5",
                             "I asked myself questions on neonatal resuscitation before I began learning using LIFE.":"Q6",
                             "I pre-planned my study time to better accomplish my learning tasks using LIFE":"Q7",
                             "I asked myself how what I’m learning in LIFE is related to what I already know":"Q8",
                             "I changed strategies in subsequent plays within LIFE when I did not meet my personal learning targets":"Q9",
                             "I had difficulty understanding new information in the LIFE scenarios":"Q10",
                             "While learning through LIFE, I made notes to help me understand":"Q11",
                             "I tried to match LIFE content with other sources of information":"Q12",
                             "Previous work experience was useful when learning through LIFE":"Q13",
                             "The score at the end of the session reflected how well I had learned":"Q14",
                             "I have a good sense of what I have learned through the LIFE app":"Q15",
                             "If I am having trouble learning, I prefer to figure it out by myself":"Q16",
                             "If I did not understand a task, I would prefer help to be provided before any initial attempt at it.":"Q17",
                             "I had access to peers for help when needed":"Q18",
                             "When I needed help, I asked my colleagues for more information":"Q19",
                             "The help I asked from my colleagues was different from the type of feedback LIFE provided me with.":"Q20"},inplace=True)
srl_data_form.Level = 'General Officer'
srl_data_form['User']=np.nan
for i in srl_data_form.Username.unique().tolist():
    user_id = users_list.User[users_list.Email==i].tolist()
    if len(user_id) > 0:
        srl_data_form.loc[srl_data_form.Username==i,['User']] = user_id
srl_user_life_google = srl_data_form.User.dropna().tolist()
srl_data_form.drop(['Username'],axis=1,inplace=True)
srl_data_mplus = pd.concat([srl_data_firebase,srl_data_form])
srl_data_mplus.reset_index(inplace=True,drop=True)
srl_data_mplus['Platform'] = 'LIFE'
srl_data_mplus = srl_data_mplus[['User','Cadre','Level','Age', 'Experience','Platform', 'Q1', 'Q2', 'Q3','Q4', 'Q5', 'Q6', 'Q7', 'Q8', 'Q9',
                                 'Q10', 'Q11', 'Q12', 'Q13', 'Q14', 'Q15', 'Q16', 'Q17', 'Q18', 'Q19', 'Q20']]
#srl_data_mplus.to_csv('D:/DPhil - University of Oxford/Data/SRL.csv',index=False)
print("LIFE Survey respondents: "+str(srl_data_mplus.shape[0]))
srl_data_mplus.tail()
users_list[users_list.User.isin(srl_data_mplus.User) & users_list.User.isin(play_data.User)].StudyGroup.value_counts()
print("LIFE SRL learners missing user IDs: "+ str(srl_data_mplus[srl_data_mplus.User.isnull()].shape[0]))
srl_data_daktari = pd.read_csv(ROOT_DATA+'SRL_Daktari_Online.csv')
srl_data_daktari.drop(['Timestamp','What is your sex?'],axis=1,inplace=True)
srl_data_daktari.rename(columns={"What is your age (in years)":"Age",
                              "What is your clinical cadre?":"Cadre",
                              "What is your current status of practice?":"Level",
                              "What is your experience level in years?":"Experience",
                              'I had personal goals for the Daktari Online course(s) I took':'Q1',
                               'I had realistic performance targets for Daktari Online course(s) I took':'Q2',
                               'Goals helped me manage my learning through Daktari Online':'Q3',
                               'When planning  learning through Daktari Online, I adapted strategies that have worked in the previous round':'Q4',
                               'For the Daktari Online course(s) I took, I considered alternative options not provided which might be better solutions':'Q5',
                               'I asked myself questions about the online course I was considering taking before I began learning using Daktari Online.':'Q6',
                               'I pre-planned my study time to better accomplish my learning tasks using Daktari Online':'Q7',
                               'I asked myself how what I’m learning in Daktari Online is related to what I already know':'Q8',
                               'I changed strategies in subsequent courses within Daktari Online when I did not meet my personal learning targets':'Q9',
                               'I had difficulty understanding new information in the Daktari Online course(s) I took':'Q10',
                               'While learning through Daktari Online, I made notes to help me understand':'Q11',
                               'I tried to match Daktari Online content with other sources of information':'Q12',
                               'Previous work experience was useful when learning through Daktari Online':'Q13',
                               'The score at the end of the session reflected how well I had learned':'Q14',
                               'I have a good sense of what I have learned through Daktari Online':'Q15',
                               'If I am having trouble learning, I prefer to figure it out by myself':'Q16',
                               'If I did not understand a task, I would prefer help to be provided before any initial attempt at it.':'Q17',
                               'I had access to peers for help when needed':'Q18',
                               'When I needed help, I asked my colleagues for more information':'Q19',
                               'The help I asked from my colleagues was different from the type of feedback Daktari Online provided me with.':'Q20'},inplace=True)
srl_data_daktari['Platform']='Daktari Online'
srl_data_daktari = srl_data_daktari[['Username','Cadre','Level','Age', 'Experience','Platform', 'Q1', 'Q2', 'Q3','Q4', 'Q5', 'Q6', 
                                     'Q7', 'Q8', 'Q9', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14', 'Q15', 'Q16', 'Q17', 'Q18', 'Q19', 'Q20']]

srl_data_daktari['User']=np.nan
for i in srl_data_daktari.Username.unique().tolist():
    user_id = users_list.User[users_list.Email==i].tolist()
    if len(user_id) > 0:
        srl_data_daktari.loc[srl_data_daktari.Username==i,['User']] = user_id
srl_data_daktari.drop(['Username'],axis=1,inplace=True)       
srl_data_daktari.tail()
srl_data_daktari.shape[0]
srl_mplus = srl_data_clean.copy()

users_once = play_data.User[play_data.Complete_Plays==1].unique().tolist()
users_multi = play_data.User[play_data.Complete_Plays>1].unique().tolist()

srl_mplus['Complete']=1
users_list['Complete']=np.nan
users_list.loc[users_list.User.isin(users_once),['Complete']]=0
users_list.loc[users_list.User.isin(users_multi),['Complete']]=1

srl_mplus.loc[srl_mplus.index.isin(users_once),['Complete']]=0
srl_mplus.reset_index(drop=True,inplace=True)
users_list.tail()
print(srl_mplus.Complete.value_counts())<jupyter_output>1    137
0     33
Name: Complete, dtype: int64<jupyter_text>Differences in Experiment Group: Variable*Drop-out rate<jupyter_code>combined_pilot = play_data[['User','Session','Question','Try','Time','Feedback','Correct']]
combined_pilot.head()
user_background.head()
from scipy import stats

users_list_use = user_background
users_list_use = users_list_use[~(users_list_use.Cadre.isnull())] 

users_summary=users_list_use[['Clinician','Cadre','Level','Age','Experience','ETAT','StudyGroup','No_Session','No_Session_Complete']]
users_summary=users_summary[users_summary.Clinician]
users_summary.loc[users_summary.Level=='General OfficerStudentIntern',['Level']]='Student'
users_summary.loc[users_summary.Level=='StudentIntern',['Level']]='Student'
users_summary.loc[users_summary.Cadre=='Clinical OfficerDoctor',['Cadre']]='Clinical Officer'
users_summary.loc[users_summary.Age.isnull(),['Age']]=0
users_summary.Age = users_summary.Age.astype(str)
users_summary.Age = users_summary.Age.str[:2]
users_summary.Age = users_summary.Age.astype(int)

users_summary.loc[users_summary.Experience.isnull(),['Experience']]=0
users_summary.Experience = users_summary.Experience.astype(str)
users_summary.Experience = users_summary.Experience.str[:2]
users_summary.Experience = users_summary.Experience.astype(int)

def remove_na(column_data,col,frame_cont):
    column_data = column_data[~(column_data[col].isnull())]
    column_data[col] = column_data[col].astype(float) 
    column_data = column_data[column_data[col] > 0]
    
    #Mean
    Ctrl_List = column_data[col][column_data['StudyGroup']==1]
    Exp_List = column_data[col][column_data['StudyGroup']==2]
    p_value = np.round(stats.ttest_ind(Ctrl_List.tolist(),Exp_List.tolist(), equal_var = False),3)[1]
        
    res = column_data.groupby('StudyGroup')[col].mean()
    res = res.to_frame()
    res.reset_index(inplace=True)
    res=res[res.StudyGroup != -1]
    res[col]=round(res[col],2)
    res['Indicator'] = 'Mean'
    
    #SD
    res_sd = column_data.groupby('StudyGroup')[col].std()
    res_sd = res_sd.to_frame()
    res_sd.reset_index(inplace=True)
    res_sd=res_sd[res_sd.StudyGroup != -1]
    res_sd[col]=round(res_sd[col],2)
    res_sd['Indicator'] = 'SD'
    
    #Count
    res_count = column_data.groupby('StudyGroup')[col].count()
    res_count = res_count.to_frame()
    res_count.reset_index(inplace=True)
    res_count = res_count[res_count.StudyGroup != -1]
    res_count[col]=res_count[col].astype(int)
    res_count['Indicator'] = 'N'
        
    res = pd.concat([res,res_sd,res_count])
    
    res = res.pivot_table(col,['Indicator'],'StudyGroup')
    res.rename(columns={1:"Ctrl",2:"Exp"},inplace=True)
    
    #print(stats.ttest_ind(rvs1,rvs2, equal_var = False))
    
    results_col = pd.DataFrame({
        'Column':col,
        'Control': str(res['Ctrl'][0])+" ("+str(res['Ctrl'][2])+", "+str(int(res['Ctrl'][1]))+")",
        'Experiment': str(res['Exp'][0])+" ("+str(res['Exp'][2])+", "+str(int(res['Exp'][1]))+")",
        'P-Value': p_value
    },index=[0])
    frame_cont = pd.concat([frame_cont,results_col])
    
    return frame_cont

def remove_na_new(column_data,col,frame_cont):
    column_data = column_data[~(column_data[col].isnull())]
    column_data[col] = column_data[col].astype(float) 
    column_data = column_data[column_data[col] > 0]
    
    #Mean
    Ctrl_List = column_data[col][column_data['Group']=='Control']
    Exp_List = column_data[col][column_data['Group']=='Experiment']
    p_value = np.round(stats.ttest_ind(Ctrl_List.tolist(),Exp_List.tolist(), equal_var = False),3)[1]
        
    res = column_data.groupby('Group')[col].mean()
    res = res.to_frame()
    res.reset_index(inplace=True)
    res[col]=round(res[col],2)
    res['Indicator'] = 'Mean'
    
    #SD
    res_sd = column_data.groupby('Group')[col].std()
    res_sd = res_sd.to_frame()
    res_sd.reset_index(inplace=True)
    res_sd[col]=round(res_sd[col],2)
    res_sd['Indicator'] = 'SD'
    
    res = pd.concat([res,res_sd])
    
    res = res.pivot_table(col,['Indicator'],'Group')
    res.rename(columns={1:"Control",2:"Experiment"},inplace=True)
    
    
    #print(stats.ttest_ind(rvs1,rvs2, equal_var = False))
    
    results_col = pd.DataFrame({
        'Column':col,
        'Control': str(res['Control'][0])+" ("+str(res['Control'][1])+")",
        'Experiment': str(res['Experiment'][0])+" ("+str(res['Experiment'][1])+")",
        'P-Value': p_value
    },index=[0])
    frame_cont = pd.concat([frame_cont,results_col])
    
    return frame_cont

def get_summary_frame(users_summary):
    
    frame_cont = pd.DataFrame()
    cols_summary_cont = ['Age','Experience','No_Session','No_Session_Complete']
    for i in cols_summary_cont:
        frame_cont = remove_na(users_summary[['StudyGroup',i]],i,frame_cont)  
        
    frame_cont.reset_index(inplace=True,drop=True)
    
    users_summary['LevelI'] = 0
    users_summary.loc[~(users_summary.Level.isnull()),['LevelI']] = 1
    
    level_frame = users_summary.groupby(['StudyGroup','Cadre'])['LevelI'].sum()
    level_frame = level_frame.to_frame()
    level_frame.reset_index(inplace=True)
    res = level_frame.pivot_table('LevelI',['Cadre'],'StudyGroup')
    res.reset_index(inplace=True)
    res.rename(columns={'Cadre':'Column',1:"Control",2:"Experiment"},inplace=True)
    
    users_summary['CadreI'] = 0
    users_summary.loc[~(users_summary.Level.isnull()),['CadreI']] = 1
    
    lvl_frame = users_summary.groupby(['StudyGroup','Level'])['CadreI'].sum()
    lvl_frame = lvl_frame.to_frame()
    lvl_frame.reset_index(inplace=True)
    res_lvl= lvl_frame.pivot_table('CadreI',['Level'],'StudyGroup')
    res_lvl.reset_index(inplace=True)
    res_lvl.rename(columns={'Level':'Column',1:"Control",2:"Experiment"},inplace=True)
    res_lvl
    
    etat_frame = (users_summary.groupby(['StudyGroup'])['ETAT'].count()).to_frame()
    etat_frame.reset_index(inplace=True)
    etat_frame = etat_frame[etat_frame.StudyGroup!=-1]
    etat_frame['Indicator'] = 'N'
    etat_frame = etat_frame.pivot_table('ETAT',['Indicator'],'StudyGroup')
    etat_frame.reset_index(inplace=True)
    etat_frame.rename(columns={'Indicator':'Column',1:"Control",2:"Experiment"},inplace=True)
    
    etat_done_frame = (users_summary.groupby(['StudyGroup'])['ETAT'].sum()).to_frame()
    etat_done_frame.reset_index(inplace=True)
    etat_done_frame = etat_done_frame[etat_done_frame.StudyGroup!=-1]
    etat_done_frame['Indicator'] = 'Done_ETAT'
    etat_done_frame = etat_done_frame.pivot_table('ETAT',['Indicator'],'StudyGroup')
    etat_done_frame.reset_index(inplace=True)
    etat_done_frame.rename(columns={'Indicator':'Column',1:"Control",2:"Experiment"},inplace=True)
    etat_done_frame

    frame_cont = pd.concat([frame_cont,res,res_lvl,etat_done_frame,etat_frame])
    frame_cont.reset_index(inplace=True,drop=True)
    frame_cont.rename(columns={'Column':'Indicator'},inplace=True)
    frame_cont.reset_index()
    
    return frame_cont

all_summary = get_summary_frame(users_summary)
complete_users_summary = users_summary[users_summary.No_Session_Complete > 1.0]
complete_summary = get_summary_frame(complete_users_summary)
incomplete_users_summary = users_summary[users_summary.No_Session_Complete < 2.0]
incomplete_summary = get_summary_frame(incomplete_users_summary)
users_recruited.head()
#Create the table mike requested
frame_cont = pd.DataFrame()
cols_summary_cont = ['Sessions_Started','Sessions_Completed','Time','Question','Performance']
for i in cols_summary_cont:
    frame_cont = remove_na_new(users_recruited[['Group',i]],i,frame_cont)  
frame_cont.reset_index(inplace=True,drop=True)
frame_cont.head()
#Create the table mike requested
frame_cont = pd.DataFrame()
users_recruited_use = users_recruited[users_recruited.User.isin(experiment_sessions.User)]
cols_summary_cont = ['Sessions_Started','Sessions_Completed','Time','Question','Performance']
for i in cols_summary_cont:
    frame_cont = remove_na_new(users_recruited_use[['Group',i]],i,frame_cont)  
frame_cont.reset_index(inplace=True,drop=True)
frame_cont.head()
etat_frame = (users_recruited.groupby(['Group'])['ETAT'].sum()).to_frame()
etat_frame.reset_index(inplace=True)
etat_frame['Indicator'] = 'N'
etat_frame = etat_frame.pivot_table('ETAT',['Indicator'],'Group')
etat_frame.reset_index(inplace=True)
etat_frame.rename(columns={'Indicator':'Column',1:"Control",2:"Experiment"},inplace=True)
etat_frame
#def test_drop_diff(col)
drop_rate = users_summary[['Age','Experience','No_Session','No_Session_Complete','StudyGroup']]
complete = drop_rate[drop_rate.No_Session_Complete > 1]
incomplete = drop_rate[drop_rate.No_Session_Complete < 2]

for i in ['Age','Experience','No_Session','No_Session_Complete']:
    complete_ind_exp = complete[i][complete.StudyGroup==2]
    incomplete_ind_exp = incomplete[i][incomplete.StudyGroup==2]
    
    complete_ind_ctrl = complete[i][complete.StudyGroup==1]
    incomplete_ind_ctrl = incomplete[i][incomplete.StudyGroup==1]
    
    
    p_value = np.round(stats.ttest_ind(complete_ind_exp.tolist(),incomplete_ind_exp.tolist(), equal_var = False),3)[1]
    print(i)
    print(p_value)
    print()
#def test_drop_diff(col)
drop_rate = users_summary[['Age','Experience','No_Session','No_Session_Complete','StudyGroup']]
complete = drop_rate[drop_rate.No_Session_Complete > 1]
incomplete = drop_rate[drop_rate.No_Session_Complete < 2]

for i in ['Age','Experience','No_Session']:
    complete_ind = complete[i].tolist()
    incomplete_ind = incomplete[i].tolist()
       
    p_value = np.round(stats.ttest_ind(complete_ind,incomplete_ind, equal_var = True),3)[1]
    print(i)
    print(p_value)
    print()
all_summary
complete_summary
incomplete_summary<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1462281946715053, 'fraction_numerical': 0.016087886028421032, 'mean_word_length': 4.498444213957623, 'pattern_counts': {'":': 64, '<': 92, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 75, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '17', 'dir': 'jupyter-structured-clean-dedup', 'id': '636617', 'license': 'MIT', 'n_tokens_mistral': 39768, 'n_tokens_neox': 37773, 'n_words': 4691, 'path': 'Experiment/01_LIFE_Firebase.ipynb', 'repo_name': 'daisichela/Statistical-Programming-Projects', 'size': '111410'}