packages = [
'pandas',
'jinja2',
]
#import os
#import asyncio
import pandas as pd
#import numpy as np # CHECK IF NEEDED
from pandas import set_option, read_csv
import io
import gc
import jinja2
#import pyperclip
######## Are those form js package ?? YES!!! ########
from js import document, Blob, URL # NECESSARY FOR FILE DOWNLOAD
from js import Uint8Array
from js import TextDecoder
#from js import FileReader
#from js import console
######## Are those form js package ?? ########
from pyscript import Element
from pyscript import display
from pyscript import create_proxy
#### GLOBALS ####
data = ''
dload_df = pd.DataFrame()
dload_df_ok = False
Token = 'Version'
header_line = [] # The way it was coded, it's a list, NOT string
headerline_index = 0 # -1 for detecting invalid CSV file
fileToAnalyse = ''
sepr = 1
ele_id_title = Element('id_title')
ele_accmin = Element('accmin')
ele_content = Element('content')
ele_rtables = Element('rtables')
ele_tcrmax = Element('tcrmax')
ele_filemsg = Element('file_msg')
## =============== PROCESS CALLBACK FOR FILE INPUT DIALOG ================
async def process_file(event):
global headerline_index, fileToAnalyse, data, dload_df_ok
dload_df_ok = False # INDICATES IF DOWNLOAD DATAFRAME IS ALLRIGHT
headerline_index = 0
fileList = event.target.files.to_py()
display('Please, choose an IRAP text datafile', target='file_msg', append=False)
#ele_filemsg.write('ail')
#print(type(file_buf))
for f in fileList:
fileToAnalyse = f.name
##==## print('Input CSV file :' + fileToAnalyse)
data = Uint8Array.new(await f.arrayBuffer())
##==## print('after await')
data = TextDecoder.new().decode(data)
# display(type(data), target='msg', append=False)
i = 0
line_list = []
flag = False
data1 = data[0:1000000].splitlines()
## try:
for line_list in data1:
if flag:
break
if Token in line_list:
header_line = data1[i + 1]
flag = True
else:
i += 1
## except:
if not flag:
display("Seems not to be a valid IRAP text file", target='file_msg', append=False)
return
display("This is a valid IRAP text file", target='file_msg', append=False)
headerline_index = data1.index(header_line)
# CLEAR TITLE OF RESULT TABLE :
ele_rtables.clear()
# CLEAR MEMORY SPACES FOR THOSE GUYS (ALBEIT GARBAGE COLLECTOR)
### data = '' # NOT THIS ONE !!!
data1 = []
## f.close()
## =============== PROCESS CALLBACK FOR STATISTCS_1 BUTTON ================
def bt_stats1():
global fileToAnalyse, dload_df, dload_df_ok
global headerline_index, data # , state
display('Success! You may now download your results.', target='file_msg', append=False)
ele_rtables.clear()
if headerline_index == 0:
display('Please, choose a TXT file first.', target='file_msg', append=False)
return
buff = io.StringIO(data) # <<<<============ SOLUTION !!!!!!
columns_to_use = ['participantCode', 'startingRule', 'isTestBlock', 'blockPairNumber',
'currentRule', 'trialNumber', 'trialType', 'timeToFirstAnswer',
'timeToCorrectResponse', 'accuracy']
PC='participantCode'; SRL='startingRule'; ITB='isTestBlock'; BPN='blockPairNumber';
CRL='currentRule'; TN='trialNumber'; TT='trialType'; TFA='timeToFirstAnswer';
TCR='timeToCorrectResponse'; ACU='accuracy'
set_option('display.max_rows', None)
set_option('display.max_columns', None)
## SETS THE FOALTING FORMAT FOR TWO DECINALS, ALTERNATIVELY USE THE .round(2)
## METHOD FOR THE mean VALUE :
pd.options.display.float_format = '{:,.2f}'.format
pd.set_option("display.colheader_justify","right")
### ==============================================
df = read_csv(buff,
sep='\t',
header=headerline_index,
index_col=False,
usecols=columns_to_use,
#on_bad_lines='warn', # 'error' , 'warn', 'skip'
#error_bad_lines=False,
#header=None,
engine='python', # 'c' , 'python' , 'pyarrow'
)
buff.close()
df = df[df[ITB] == bool(1)]
try:
TCRMAX = int(ele_tcrmax.element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
TCRMAX = 2000
df = df.groupby([PC, TT])[[TCR]].mean() ### .round(2)
df = df[df[TCR] >= TCRMAX] # the means per partic per trial type that exceede TCRMAX
# SAVE THE DATAFRAME TO A GLOBAL VARIABLE FOR DOWNLOADING:
dload_df = df
styles = [{'selector':"*", 'props':[
("font-family" , 'Tahoma'),
("font-size" , '18px'),
("margin" , "15px auto"),
("border" , "4px solid #6C6C6C")]},
{"selector": "th", "props": [("text-align", "center"), ("background-color", "#FFE2D2")]},
{"selector": "td", "props": [("text-align", "center"), ("padding", "5px 7px")]},
]
df = df.style.set_table_styles(styles)
ele_content.clear()
#### (2024-04-17): CHANGE WRITE TO DISPLAY : SAME RESULTS: CHECK WHICH ONE HAS BETTER PERFORMANCE AND RESOURCE USAGE
#ele_content.write(df, append=False)
display(df, target='content', append = False)
#### elem = Element('id_title')
ele_id_title.write(f'Rule Violation: Means, per Participant and per Trial Type of each, considering only Test Blocks, of Time to Correct Response, identifying those > {TCRMAX} (Max Latency).', append=False)
dload_df_ok = True
del(df)
gc.collect()
## =============== PROCESS CALLBACK FOR STATISTCS_2 BUTTON ================
def bt_stats2():
global fileToAnalyse, dload_df, dload_df_ok
global headerline_index, data, ele_id_title, ele_accmin
display('Success! You may now download your results.', target='file_msg', append=False) # CLEARS THE PREVIOUS MESSAGE
buff = io.StringIO(data)
### display(dir(buff), target='msg')
if headerline_index == 0:
display('Please, choose a TXT data file first.', target='file_msg', append=False)
return
columns_to_use = ['participantCode', 'startingRule', 'isTestBlock', 'blockPairNumber',
'currentRule', 'trialNumber', 'trialType', 'timeToFirstAnswer',
'timeToCorrectResponse', 'accuracy']
PC='participantCode'; SRL='startingRule'; ITB='isTestBlock'; BPN='blockPairNumber';
CRL='currentRule'; TN='trialNumber'; TT='trialType'; TFA='timeToFirstAnswer';
TCR='timeToCorrectResponse'; ACU='accuracy'
set_option('display.max_rows', None)
set_option('display.max_columns', None)
## SETS THE FOALTING FORMAT FOR TWO DECINALS, ALTERNATIVELY USE THE .round(2)
## METHOD FOR THE mean VALUE :
pd.options.display.float_format = '{:,.2f}'.format
pd.set_option("display.colheader_justify","right") ## center"
### ==============================================
df = read_csv(buff,
sep='\t',
header=headerline_index,
index_col=False,
usecols=columns_to_use,
#on_bad_lines='warn', # 'error' , 'warn', 'skip'
#error_bad_lines=False,
#header=None,
engine='python', # 'c' , 'python' , 'pyarrow'
)
buff.close()
df = df[df[ITB] == bool(1)]
try:
ACCMIN = float((ele_accmin).element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
ACCMIN = 0.8
df = df.groupby([PC, TT])[[ACU]].mean() ### .round(2)
df = df[df[ACU] <= ACCMIN] # the means per partic per trial type that fall bellow ACCMIN
styles = [{'selector':"*", 'props':[
("font-family" , 'Tahoma'),
("font-size" , '18px'),
("margin" , "15px auto"),
("border" , "4px solid #6C6C6C")]},
{"selector": "th", "props": [("text-align", "center"), ("background-color", "#FFE2D2")]},
{"selector": "td", "props": [("text-align", "center"), ("padding", "5px 7px")]},
]
# SAVE THE DATAFRAME IN A GLOBAL VARIABLE TO DWNLOAD IT LATER :
dload_df = df
df = df.style.set_table_styles(styles)
ele_content.clear()
display(df, target='content', append=False)
######## ele_id_title = Element('id_title')
ele_id_title.write(f'Rule Violation: Means of Accuracy, per Participant and per Trial Type of each, considering only Test Blocks, of Accuracy, identifying those that fall bellow the Accuracy Threshold (ACCMIN) for Min Accuracy = {ACCMIN}.', append=False)
dload_df_ok = True
del(df)
gc.collect()
## =============== PROCESS CALLBACK FOR STATISTCS_3 BUTTON ================
def bt_stats3():
global fileToAnalyse, dload_df, dload_df_ok
global headerline_index, data, ele_id_title, ele_accmin, ele_tcrmax
display('Success! You may now download your results.', target='file_msg', append=False)
buff = io.StringIO(data)
### display(dir(buff), target='msg')
if headerline_index == 0:
display('Please, choose a TXT data file first.', target='file_msg', append=False)
return
columns_to_use = ['participantCode', 'startingRule', 'isTestBlock', 'blockPairNumber',
'currentRule', 'trialNumber', 'trialType', 'timeToFirstAnswer',
'timeToCorrectResponse', 'accuracy']
PC='participantCode'; SRL='startingRule'; ITB='isTestBlock'; BPN='blockPairNumber';
CRL='currentRule'; TN='trialNumber'; TT='trialType'; TFA='timeToFirstAnswer';
TCR='timeToCorrectResponse'; ACU='accuracy'
set_option('display.max_rows', None)
set_option('display.max_columns', None)
## SETS THE FOALTING FORMAT FOR TWO DECINALS, ALTERNATIVELY USE THE .round(2)
## METHOD FOR THE mean VALUE :
pd.options.display.float_format = '{:,.2f}'.format
pd.set_option("display.colheader_justify","right") ## center"
### ==============================================
df = read_csv(buff,
sep='\t',
header=headerline_index,
index_col=False,
usecols=columns_to_use,
#on_bad_lines='warn', # 'error' , 'warn', 'skip'
#error_bad_lines=False,
#header=None,
engine='python', # 'c' , 'python' , 'pyarrow'
)
buff.close()
#######################################################
df = df.astype({
PC: 'int32',
ITB: 'bool',
TT: 'int32',
TCR: 'float',
ACU: 'float'
})
#######################################################
df = df[df[ITB] == bool(1)]
# GRAB AND FILTER TCRMAX :
try:
TCRMAX = int(ele_tcrmax.element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
TCRMAX = 2000
# GRAB AND FILTER ACCMIN :
try:
ACCMIN = float((ele_accmin).element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
ACCMIN = 0.8
df = df.groupby([PC, TT])[[TCR, ACU]].mean()
df = df[df[TCR] >= TCRMAX]
df = df[df[ACU] <= ACCMIN]
styles = [{'selector':"*", 'props':[
("font-family" , 'Tahoma'),
("font-size" , '18px'),
("margin" , "15px auto"),
("border" , "4px solid #6C6C6C")]},
{"selector": "th", "props": [("text-align", "center"), ("background-color", "#FFCFC0")]},
{"selector": "td", "props": [("text-align", "center"), ("padding", "5px 7px")]},
]
# SAVE THE DATAFRAME IN A GLOBAL VARIABLE TO DWNLOAD IT LATER :
dload_df = df
df = df.style.set_table_styles(styles)
ele_content.clear()
display(df, target='content', append=False)
ele_id_title.write(f'Rule Breach 1 AND Rule Breach 2.', append=False)
dload_df_ok = True
del(df)
gc.collect()
## =============== PROCESS CALLBACK FOR STATISTCS_4 BUTTON ================
def bt_stats4():
global fileToAnalyse, dload_df, dload_df_ok
global headerline_index, data, ele_id_title, ele_accmin, ele_tcrmax
display('Success! You may now download your results.', target='file_msg', append=False)
buff = io.StringIO(data)
if headerline_index == 0:
display('Please, choose a TXT data file first.', target='file_msg', append=False)
return
columns_to_use = ['participantCode', 'startingRule', 'isTestBlock', 'blockPairNumber',
'currentRule', 'trialNumber', 'trialType', 'timeToFirstAnswer',
'timeToCorrectResponse', 'accuracy']
PC='participantCode'; SRL='startingRule'; ITB='isTestBlock'; BPN='blockPairNumber';
CRL='currentRule'; TN='trialNumber'; TT='trialType'; TFA='timeToFirstAnswer';
TCR='timeToCorrectResponse'; ACU='accuracy'
set_option('display.max_rows', None)
set_option('display.max_columns', None)
## SETS THE FOALTING FORMAT FOR TWO DECINALS, ALTERNATIVELY USE THE .round(2)
## METHOD FOR THE mean VALUE :
pd.options.display.float_format = '{:,.2f}'.format
pd.set_option("display.colheader_justify","right") ## center"
### ==============================================
df = read_csv(buff,
sep='\t',
header=headerline_index,
index_col=False,
usecols=columns_to_use,
#on_bad_lines='warn', # options: 'error' , 'warn', 'skip'
#error_bad_lines=False,
#header=None,
engine='python', # options: 'c' (default) , 'python' , 'pyarrow'
)
buff.close()
#######################################################
df = df.astype({
PC: 'int32',
ITB: 'bool',
TT: 'int32',
TCR: 'float',
ACU: 'float'
})
#######################################################
# GRAB AND VALIDATE TCRMAX :
try:
TCRMAX = int(ele_tcrmax.element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
TCRMAX = 2000
# GRAB AND VALIDATE ACCMIN :
try:
ACCMIN = float((ele_accmin).element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
ACCMIN = 0.8
df = df[df[ITB] == bool(1)] # STEP 1
df = df[df[ITB] <= 10000] # STEP 2
df = df.groupby([PC, CRL, TT])[[TCR, ACU]].mean()
df = df[df[TCR] >= TCRMAX]
df = df[df[ACU] <= ACCMIN]
#print(df.head(50))
styles = [{'selector':"*", 'props':[
("font-family" , 'Tahoma'),
("font-size" , '18px'),
("margin" , "15px auto"),
("border" , "4px solid #6C6C6C")]},
{"selector": "th", "props": [("text-align", "center"), ("background-color", "#FFD1B8")]},
{"selector": "td", "props": [("text-align", "center"), ("padding", "5px 7px")]},
]
# SAVE THE DATAFRAME IN A GLOBAL VARIABLE TO DWNLOAD IT LATER :
dload_df = df
df = df.style.set_table_styles(styles)
ele_content.clear()
display(df, target='content', append=False)
ele_id_title.write(f'Rule Violation: Means of Accuracy and Latency, per Participant, per Trial Type, and per Current Rule (Con, Incon) of each, considering only Test Blocks, identifying those that fall bellow the Accuracy Threshold of {ACCMIN} and above the Latency threshold of {TCRMAX}. There may be more results here than when the means average out the two different types of block.', append=False)
dload_df_ok = True
del(df)
gc.collect()
## =============== PROCESS CALLBACK FOR STATISTCS_5 BUTTON ================
def bt_stats5():
global fileToAnalyse, dload_df, dload_df_ok
global headerline_index, data, ele_id_title, ele_accmin, ele_tcrmax
display('Success! You may now download your results.', target='file_msg', append=False)
buff = io.StringIO(data)
if headerline_index == 0:
display('Please, choose a TXT data file first.', target='file_msg', append=False)
return
columns_to_use = ['participantCode', 'startingRule', 'isTestBlock', 'blockPairNumber',
'currentRule', 'trialNumber', 'trialType', 'timeToFirstAnswer',
'timeToCorrectResponse', 'accuracy']
PC='participantCode'; SRL='startingRule'; ITB='isTestBlock';
BPN='blockPairNumber'; CRL='currentRule'; TN='trialNumber'; TT='trialType'; TFA='timeToFirstAnswer';
TCR='timeToCorrectResponse'; ACU='accuracy'
set_option('display.max_rows', None)
set_option('display.max_columns', None)
## SETS THE FOALTING FORMAT FOR TWO DECINALS, ALTERNATIVELY USE THE .round(2)
## METHOD FOR THE FLOAT TYPE VALUES :
pd.options.display.float_format = '{:,.5f}'.format
pd.set_option("display.colheader_justify","right") ## center"
### ==============================================
df = read_csv(buff,
sep='\t',
header=headerline_index,
index_col=False,
usecols=columns_to_use,
#on_bad_lines='warn', # 'error' , 'warn', 'skip'
#error_bad_lines=False,
#header=None,
engine='python', # 'c' , 'python' , 'pyarrow'
).rename(columns={'participantCode': 'Part Code', 'isTestBlock': ITB, 'currentRule': CRL, \
'trialType': 'Trial Type', 'timeToFirstAnswer': TFA, 'timeToCorrectResponse': TCR, 'accuracy': ACU})
buff.close()
#######################################################
df = df.astype({
'Part Code': 'int64',
ITB: 'bool',
CRL: 'int64',
'Trial Type': 'int64',
TCR: 'float',
ACU: 'float'
})
#######################################################
#print(df.dtypes)
# GRAB AND VALIDATE TCRMAX :
try:
TCRMAX = int(ele_tcrmax.element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
TCRMAX = 2000
# GRAB AND VALIDATE ACCMIN :
try:
ACCMIN = float((ele_accmin).element.value)
except:
display("Not a valid float value. Using default.", target='msg', append=False)
ACCMIN = 0.8
df = df[df[ITB] == bool(1)] # STEP 1 (MAYBE NOT NEEDED, CAUSE THE DATA IS ALREADY FILTERED BY THE ASTYPE() ABOVE.
df = df[df[TCR] <= 10000] # STEP 2
df = df[['Part Code', BPN, CRL, 'Trial Type', TCR, ACU]]
# STEP 3:
# FROM CODEIUM SUGGESTION: (OK !!)
## =========================================
# Define a custom filter function
def filter_groups(group):
# Calculate the number of rows in the group where TCR <= 300.0
num_rows_tcr_less_equal_300 = group[group[TCR] <= 300.0].shape[0]
# Check if this is greater than 10% of the total number of rows in the group
if num_rows_tcr_less_equal_300 > 0.1 * group.shape[0]:
return False # Exclude this group from the DataFrame
return True # Include this group in the DataFrame
# Apply the custom filter function to each group and transform the DataFrame
df1 = df.groupby('Part Code').filter(filter_groups)
## =========================================
df1 = df1.groupby(['Part Code', 'blockPairNumber', 'Trial Type']).apply(lambda x: pd.DataFrame({
'MeanTCR1': [x[TCR].loc[x[CRL] == 1].mean()],
'MeanTCR2': [x[TCR].loc[x[CRL] == 2].mean()],
'Std': [x[TCR].std(ddof=1)]
}))
# ================================================
df1['MeanTCR2_1'] = df1['MeanTCR2'] - df1['MeanTCR1'] # Note: some often, errors occur here. (recommesded: groupKeys=False)
df1['DIRAP_Score'] = df1['MeanTCR2_1'] / df1['Std']
df1 = df1.groupby(['Part Code', 'Trial Type'])['DIRAP_Score'].mean().to_frame('D_Scores')
# SAVE THE DATAFRAME IN A GLOBAL VARIABLE TO DOWNLOAD IT LATER :
#dload_df = df1
df1 = df1.pivot_table(df1, index=['Part Code'], columns=['Trial Type'])
# SAVE THE DATAFRAME IN A GLOBAL VARIABLE TO DOWNLOAD IT LATER :
dload_df = df1
styles = [{'selector':"*", 'props':[
("font-family" , 'Tahoma'),
("font-size" , '18px'),
("margin" , "15px auto"),
("border" , "4px solid #71797E")]},
{"selector": "th", "props": [("text-align", "center"), ("background-color", "#FFDACC")]},
{"selector": "td", "props": [("text-align", "center"), ("padding", "6px 8px")]},
]
df1 = df1.style.set_table_styles(styles)
ele_content.clear()
display(df1, target='content', append=False)
ele_id_title.write(f'Overall D-IRAP Scores per Participant and per Trial Type of each, considering only Test Blocks.', append=False)
dload_df_ok = True
# JUST IN CASE, TO CLEAN UP THE MEMORY :
del(df)
del(df1)
gc.collect()
## ========================================================
## THIS FUNCTON BOUNDS THE ACTION OF PRESSING THE FILE SELECT BUTTON TO ITS
## CALLBACK FUNCTION "process_file()"
def setup_button_inp_file():
'''
# Create a Python proxy for the callback function
# process_file() is your function to process events from FileReader
'''
file_event = create_proxy(process_file)
# Set the listener to the callback
e = document.getElementById("file_input")
e.addEventListener("change", file_event, False)
def setup_bt_stats1():
### print('Inside setup_bt_stats1')
# Create a Python proxy for the callback function
"""
This function to process events from the action of pressing bt_stats1, which has an id of "stats1"
"""
#button1_event = create_proxy(setup_bt_stats1)
button1_event = create_proxy(bt_stats1)
# Set the listener to the callback
e = document.getElementById("stats1")
e.addEventListener("click", button1_event, False)
def setup_bt_stats2():
### print('Inside setup_bt_stats2')
# Create a Python proxy for the callback function
'''
This function to process events from the action of pressing
bt_stats2, which has an id of "stats2"
'''
#button2_event = create_proxy(setup_bt_stats2)
button2_event = create_proxy(bt_stats2)
# Set the listener to the callback
e = document.getElementById("stats2")
e.addEventListener("click", button2_event, False)
def setup_bt_stats3():
# Create a Python proxy for the callback function
'''
This function to process events from the action of pressing
bt_stats3, which has an id of "stats3"
'''
button3_event = create_proxy(bt_stats3)
#button3_event = create_proxy(setup_bt_stats3)
# Set the listener to the callback
e = document.getElementById("stats3")
e.addEventListener("click", button3_event, False)
def setup_bt_stats4():
# Create a Python proxy for the callback function
'''
This function to process events from the action of pressing
bt_stats4, which has an id of "stats4"
'''
button4_event = create_proxy(bt_stats4)
#button4_event = create_proxy(setup_bt_stats4)
# Set the listener to the callback
e = document.getElementById("stats4")
e.addEventListener("click", button4_event, False)
def setup_bt_stats5():
# Create a Python proxy for the callback function
'''
This function to process events from the action of pressing
bt_stats5, which has an id of "stats5"
'''
button5_event = create_proxy(bt_stats5)
#button5_event = create_proxy(setup_bt_stats5)
# Set the listener to the callback
e = document.getElementById("stats5")
e.addEventListener("click", button5_event, False)
def download_dataframe(df, sepr, default_filename='dataframe.csv'):
#global sepr
# Convert DataFrame to CSV string with necessary options for Excel compatibility
if sepr == 1:
csv_content = df.to_csv(index=True, \
sep=',', \
float_format='%.5f' \
)
else:
csv_content = df.to_csv(index=True, \
sep='\t', \
float_format='%.5f' \
)
# Create a Blob object with the contents of the CSV
blob = Blob.new([csv_content], {'type': 'text/csv'})
# Create a URL for the Blob object
object_url = URL.createObjectURL(blob)
# Create a temporary anchor element ('a') and trigger the download
temp_link = document.createElement('a')
temp_link.href = object_url
temp_link.download = default_filename
document.body.appendChild(temp_link)
temp_link.click()
# Cleanup: remove the temporary link and revoke the Blob URL
document.body.removeChild(temp_link)
URL.revokeObjectURL(object_url)
def on_dload_button_click_1(event):
global dload_df_ok, sepr
sepr = 1
event.preventDefault() # Prevent default action which can cause page reload
if not dload_df_ok:
display('Please, create dataframe table first.', target='file_msg', append=False)
return
else:
try:
download_dataframe(dload_df, sepr, 'irap_tt_analysis.csv')
display('Success! You may now download your results.', target='file_msg', append=False)
except Exception as e:
print(e, "Error downloading dataframe")
def on_dload_button_click_2(event):
global dload_df_ok, sepr
sepr = 2
event.preventDefault() # Prevent default action which can cause page reload
if not dload_df_ok:
display('Please, create dataframe table first.', target='file_msg', append=False)
return
else:
try:
download_dataframe(dload_df, sepr, 'irap_tt_analysis.csv')
display('Success! You may now download your results.', target='file_msg', append=False)
except Exception as e:
print(e, "Error downloading dataframe")
# Add the event listener to the download button :
def setup_dload_comma():
download_button_comma = document.getElementById('download_button_comma')
download_button_comma.addEventListener('click', create_proxy(on_dload_button_click_1))
def setup_dload_tab():
download_button_tab = document.getElementById('download_button_tab')
download_button_tab.addEventListener('click', create_proxy(on_dload_button_click_2))
setup_button_inp_file()
setup_bt_stats1()
setup_bt_stats2()
setup_bt_stats3()
setup_bt_stats4()
setup_bt_stats5()
setup_dload_comma()
setup_dload_tab()
Intelectual property produced during the Ulster University PhD is linked to Ulster University. This institution should be contacted regarding reuse of the source material.
Any work that uses the present resource must cite:
de Almeida, R.V., Barnes-Holmes, D. & Leslie, J.C. (2024). Differential Trial-Type Effects in an Implicit Relational Assessment Procedure: Extending the DAARRE Model. The Psychological Record. DOI: 10.1007/s40732-024-00604-1.