Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
[Unreleased]¶
Removed¶
layout.pysettings.pyContentCore.get_page_data: UseExperimentSession.valuesorExperimentSession.get_page_datainstead.
Changed¶
new way to change final page
New classes
JavaScript
Css
VerticalSpace
Row
Stack
Element
New parameters
align
width
position
showif
New attributes
element_width
showif
css_code
css_urls
js_code
js_urls
html (For deriving child classes)
template_data
TextElement
Now supports Markdown
New parameters
path
InputElement
revamped as an even stronger base clase for input elements
TextEntryElement
New parameters
placeholder
New attributes
instruction_col_width
input_col_width
Page
New attributes
fixed_width
responsive_width
Config
New Section “layout”
v1.4¶
Added¶
With this version, alfred3 gains some powerful new features. This is the overview:
The
UnlinkedDataPagecan be used to safely collect data that cannot be linked to any specific experiment session.Alfred3 now automatically generates a comprehensive raw codebook that describes your data set.
Alfred3 now offers functionality for transforming locally collected data from .json to .csv format (both automatically at the end of each session, and manually via a command line interface).
New hooks for pages and sections make it easier to tidily organize experiment code.
Details below!
New page classes¶
page.UnlinkedDataPage: Use this page to collect data that should not be linkeable to the experiment data. All data from UnlinkedDataPages will be shuffled and saved in a separate file. No timestamps or other metadata are stored that would make it possible to link an unlinked dataset to an experiment dataset. Otherwise, usage is fully equivalent to ordinary pages.page.CustomSavingPage: This is an abstract page class for advanced users. It grants you detailed control over the saving behavior of your page. Basically, you give the page its own saving agent and manually define exactly, which data will be saved. For more information, callhelp(CustomSavingPage).
Automatic codebook generation¶
Alfred now automatically generates a raw codebook from your experiment. The codebook contains descriptions for all user-input elements and can be exported as .csv or .json.
Automatic transformation of local data to .csv¶
Upon completion of an experiment session, alfred now automatically converts experiment data (including unlinked and codebook data) to .csv by default. You can control this behavior through two options in config.conf:
[general]
transform_data_to_csv = true # controls, whether to transform data or not
csv_directory = data # the .csv files will be placed in this directory
Command line interface for exporting alfred3 data¶
Through a new command line interface, you can export alfred data, both from your local save directory, and from your MongoDB storage. Standard usage is to call the CLI from your experiment directory. It automatically extracts the relevant data from your config.conf or secrets.conf.
python3 -m alfred3.export --src=local_saving_agent
Detailed description of all parameters (available also from the terminal via python3 -m alfred3.export --help )
Usage: export.py [OPTIONS]
Options:
--src TEXT The name of the configuration section in 'config.conf'
or 'secrets.conf' that defines the SavingAgent whose
data you want to export. [default: local_saving_agent]
--directory TEXT The path to the experiment whose data you want to
export. [default: Current working directory]
-h, --here With this flag, you can indicate that you want to
export .json files located in the current working
directory. [default: False]
--data_type TEXT The type of data that you want to export. Accepted
values are 'exp_data', 'unlinked', and 'codebook'. If
you specify a 'src', the function tries to infer the
data type from the 'src's suffix. (Example:
'mongo_saving_agent_codebook' would lead to 'data_type'
= 'codebook'. If you give a value for 'data_type', that
always takes precedence. If no data_type is provided and
no data_type can be inferred, 'exp_data' is used.
--missings TEXT Here, you can manually specify a value that you want to
insert for missing values.
--remove_linebreaks Indicates, whether linebreak characters should be
deleted from the file. If you don't use this flag (the
default), linebreaks will be replaced with spaces.
[default: False]
--delimiter TEXT Here, you can manually specify a delimiter for your
.csv file. You need to put the delimiter inside
quotation marks, e.g. like this: --delimiter=';'.
[default: ,]
--help Show this message and exit.
New page hooks for more control¶
All page classes now provide the possibility to define additional hooks, granting you more fine-grained control over the exact time your code gets executed. Here is a list of them:
| Hook | Explanation |
|—————–|—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————|
| on_exp_access | Hook for code that is meant to be executed as soon as a page is added to an experiment. This is your go-to-hook, if you want to have access to the experiment, but don’t need access to data from other pages. |
| on_first_show | Hook for code that is meant to be executed when a page is shown for the first time. This is your go-to-hook, if you want to have access to data from other pages within the experiment, and your code is meant to be executed only once (i.e. the first time a page is shown). |
| on_each_show | Hook for code that is meant to be executed every time the page is shown. |
| on_first_hide | Hook for code that is meant to be executed only once, when the page is hidden for the first time, before saving the page’s data. Important: Note the difference to on_close , which is executed upon final submission of the page’s data. When using on_first_hide , subject input can change (e.g., when a subject revists a page and changes his/her input). |
| on_each_hide | Hook for code that is meant to be executed every time the page is hidden, before saving the page’s data. |
| on_close | Hook for code that is meant to be executed when a page is closed. This is your go-to-hook, if you want to have the page execute code only once, when submitting the data from a page. Closing happens, when you leave a page for the first time in a HeadOpenSection (participants can revisit the page, but can’t change their input), and when you leave a page in a SegmentedSection (participants cannot go back to previous pages). That means, this hook has no effect inside a standard Section , because its pages don’t get closed. |
For now, the old hooks on_showing , on_showing_widget (both equivalent to on_each_show ) and on_hiding , as well as on_hiding_widget (both equivalent to on_each_hide ) will still work but are deprecated and will be removed in future versions. Therefore we ask you to use the new hooks from now on.
Here is an example:
from alfred3.page import Page
from alfred3.element import TextElement
class Welcome(Page):
def on_exp_access(self):
self += TextElement("This code is executed upon adding the page to the experiment.")
def on_first_show(self):
self += TextElement("This code is executed right before showing the page for the first time")
New section hooks for more control¶
The section classes also gain some hooks:
| Hook | Explanation |
| — | — |
| on_exp_access | Hook for code that is meant to be executed as soon as a section is added to an experiment. |
| on_enter | Hook for code that is meant to be executed upon entering a section in an ongoing experiment. |
| on_leave | Hook for code that is meant to be executed upon leaving a section in an ongoing experiment. This code will be executed after closing the section’s last page. |
Here is an example:
from alfred3.section import Section
from alfred3.page import Page
class Main(Section):
def on_exp_access(self):
self += Page(title="Demo Page, added upon adding the section to the experiment.")
def on_enter(self):
print("Code executed upon entering the section.")
alfred v1.3.0 (Released 2020-08-19)¶
Added¶
We defined the iadd (
+=) operator for all pages, sections and the experiment class. In many cases, it can replace a call to theappend()method of these classes. Don’t worry, theappend()method is not going away. You can use this operator…… to append elements to a page
… to append pages and sections to a sections
… to append pages and section to the experiment
Simple examples:
# (assuming correct imports)
# Append element to a page
page = Page(title="Test Page")
page += TextElement("Testtext", name="text1")
# (assuming correct imports)
# Append page and section to a section
main = Section()
second = Section()
page = Page(title="Test Page")
second += page # using the page instance from the
main += second
# (assuming correct imports)
# Append sections and pages to the experiment
exp = Experiment()
main = Section()
exp += main
When using the += operator in class definitions, you refer to “self”:
# (assuming correct imports)
class Welcome(Page):
def on_showing(self):
self += TextElement("Testtext", name="text1")
Changed¶
When downloading a template, it is now allowed to have a
.ideaand a.gitfile already present in the target directory. Otherwise, the directory must be empty.
alfred v1.2.1 (Released 2020-08-18)¶
Fixed¶
Fixed an underspecified filepath handling that caused trouble with the logging initialization under windows.
Changed¶
We made using the flask debugger easier:
If you use the command line interface, you can add the flag ‘debug’ to start an experiment in debugging mode and use flask’s builtin debugging tools. The command becomes
python -m alfred3.run -debug.If you use the small
run.py, you can passdebug=Trueas a parameter inauto_run():runner.auto_run(debug=True)
Upgraded the command line interface for downloading templates.
Most notably, the interface gained the flag ‘-h’/’–here’, that you can use to indicate that you want the template’s files to be placed directly in the ‘–path’ (by default, in the current working directory).
Instead of the ‘-b’/’–big’ and ‘-r’/’–runpy’ flags, you can now choose between variants by setting the option ‘–variant’ to ‘s’, ‘m’ (default), or ‘l’.
Enhanced handling of naming conflicts.
This is the full new usage:
Usage: template.py [OPTIONS]
Options:
--name TEXT Name of the new experiment directory. [default:
alfred3_experiment]
--path TEXT Path to the target directory. [default: Current working
directory]
--release TEXT You can specify a release tag here, if you want to use a
specific version of the template.
--variant TEXT Which type of template do you want to download? The
available options are: 's' (minimalistic), 'm' (includes
'run.py' and 'secrets.conf') and 'b' (includes subdirectory
with imported classes and instructions.) [default: m]
-h, --here If this flag is set to '-h', the template files will be
placed directly into the directory specified in '--path',
ignoring the paramter '--name'. [default: False]
--help Show this message and exit.
alfred v1.2.0 (Released 2020-07-13)¶
Added¶
Minor changes¶
We added a new page class
page.NoDataPage, which does only return the page’s tag and uid when queried by the saving agent. This will prevent any data from being saved to the standard saving agents. You can use this page, if you want to save data to an external database, separated from experimental data (e.g., if you need to save personal data).We added support for custom imports of
.pyfiles from subdirectories that are transferable to mortimer by including the packagethesmuggler. If you want to store content in an external.pyfile (which we highly recommend, as it leads to a clearer directory structure), you can import such a file by usingthesmuggler.smuggle(). Example:
# files/instructions.py
text = "This text resides in files/instructions.py"
# script.py
from thesmuggler import smuggle
inst = smuggle("files/instructions.py")
print(inst.text)
Fullscreen option for Google Chrome¶
We added an option that allows you to make experiments start in Chrome’s fullscreen (or “kiosk”) mode with hidden browser controls (forward, backward, refresh). This lowers the probability that subjects in lab experiments will mess with the browser controls. On Windows, it will only work, if Chrome is installed to a default directory and is only tested on Windows 10.
You can enable this option in your config.conf:
[experiment]
fullscreen = true # default: false
In order for this feature to work, you need to use our most recent version of run.py . There is an easy way to do this (see below)
Old run.py files will continue to work, but we strongly recommend to use the new method, because this will ensure that your experiment-running code will be updated together with alfred3.
alfred3.run module with command line interface¶
Added a module alfred3.run that contains the functionality for locally running alfred experiments. It can be used via the command line like this:
python3 -m alfred3.run
Note that you must run this code from within your experiment directory, or specifiy a path to the experiment directory with the option --path=<path> . By setting the flag -m ( --manual-open ), you can switch off the automatic opening of a browser window upon experiment startup. See python3 -m alfred3.run --help for all available options.
You can also continue to use a run.py in your experiment directory to run your experiment, if you wish. From now on, this file should look like this (watch this video for an explanation concerning the if __name__ == "__main__" protector.):
from alfred3.run import ExperimentRunner
if __name__ == "__main__":
runner = ExperimentRunner()
runner.auto_run()
This feature eliminates the need for a run.py file in your experiment directory. The API might still change in the future, so this feature is considered experimental.
If you want to gain more control over your run.py you can execute individual steps (only recommended for advanced users. Usually, this will not be necessary.):
from alfred3.run import ExperimentRunner
if __name__ == "__main__":
runner = ExperimentRunner()
runner.generate_session_id()
runner.configure_logging()
runner.create_experiment_app()
runner.set_port()
runner.start_browser_thread()
runner.print_startup_message()
runner.app.run(use_reloader=False, debug=False)
This will allow you to customize logging configuration or to extract the flask app that is created through your alfred experiment.
The former can be achieved by configuring a logger of the name
exp.<exp_id>, where<exp_id>is the experiment ID, accessible viarunner.config["exp_config"].get("metadata", "exp_id")The latter can be achieved by assigning the returned value of
runner.create_experiment_app()to an object, or by accessingrunner.appaftercreate_experiment_appwas run.
alfred3.template command line interface for experiment template¶
We have a new convenience feature for accessing the latest experiment template. Just use your terminal to execute the following command:
python3 -m alfred3.template
This will download the latest experiment template from GitHub to your current working directory, including a useful .gitignore that will automatically prevent your secrets.conf from being included in your git repository.
With the optional argument --path , you can hand over a directory path to be used instead of your current working directory.
Of course, you can still download the template manually from GitHub, if you prefer so.
Additional options allow for more flexibility. Take a look at them with the following command:
python3 -m alfred3.template --help
Changed¶
Enhanced configuration¶
If you don’t want to change the default configuration, you don’t need a
config.conffile in your experiment directory anymore.We separated the values provided in
config.confinto two files to enable easier code sharing and enhance security at the same time:config.conffrom now on holds exclusively publicly available configuration. This file is meant to be shared.secrets.confis a new configuration file that only holds secret information like database credentials. This file should never be shared. It is included in the.gitignoreof our experiment template to prevent accidental sharing.
You can now supply your own custom configuration options via
config.confandsecrets.conf. The experiment object gains aconfigand asecretsattribute, both of which are instances of a modified configparser. ConfigParser and provided the same methods for accessing options.Pay attention to the way that values are returned.
ConfigParserobjects don’t guess the type of your values. Instead, they provide specialized methods.getreturns str,getintreturns int,getfloatreturns float, andgetbooleanreturns boolean values (which should be entered as “true”/”false” or “1”/”0” inconfig.conf).All of these methods take as first argument the section and as second argument the key (as demonstrated below).
Usage example of custom cofiguration:
# config.conf
[my_section]
my_key = my_value
my_bool = true
# script.py
from alfred3 import Experiment, page, element
class Welcome(page.Page):
def on_showing(self):
my_value = self.experiment.config.get("my_section", "my_value")
text = element.TextElement(my_value)
self.append(text)
def generate_experiment(self, config=None):
exp = Experiment(config=config)
welcome = Welcome(title="Welcome page")
if exp.config.getboolean("my_section", "my_bool"):
exp.append(welcome)
return exp
Enhanced logging¶
All instances and children of
Experiment,element.Element,page.Page, andsection.Sectiongain alogattribute.The
logattribute is basically a wrapper around alogging.Logger. It behaves like a normal logger in many ways, offering the usual methodsdebug,info,warning,error,critical,exception,log, andsetLevel.If you want to access the logger object directly to apply more detailed configuration, you can do so via
log.queue_logger.
See logging documentation for more information on the levels and configuration.
Usage:
from alfred3 import Experiment, page
class Welcome(page.Page):
def on_showing(self):
self.log.info("This message will be logged on showing of the page")
def generate_experiment(self, config=None):
exp = Experiment(config=config)
exp.log.info("This message will be logged after initialization of the experiment.")
welcome = Welcome(title="Welcome page")
# Sets the log level to 'WARNING'
# The message logged above in the 'on_showing' definition will therefore
# not be logged, as it is of level 'info'
welcome.log.setLevel("WARNING")
exp.append(welcome)
Minor changes¶
You can now define an encryption key either in
secrets.confor in an environment variable namedALFRED_ENCRYPTION_KEY.
Removed¶
Removed qt-webkit support¶
We removed the option to run alfred experiments via qt-webkit. This was a rarely used feature and introduced a dependency on PySide2, which caused issues with deployment via mortimer and mod_wsgi. Specifically, the following option in config.conf is no longer available:
We removed the option to run alfred experiments via qt-webkit. This was a rarely used feature and introduced a dependency on PySide2, which caused issues with deployment via mortimer and mod_wsgi. Specifically, the following option in config.conf no longer has any effect:
[experiment]
type = qt-wk
Instead, you can turn to the new option for running experiments in Google Chrome’s fullscren (aka “kiosk”) mode (see above).
alfred3 v1.1.5 (Released 2020-05-13)¶
Fixed¶
Fixed a bug in the parsing of the auth_source parameter in
config.conf
alfred3 v1.1.4 (Released 2020-05-05)¶
Announcement: Released to PyPi under the new name alfred3¶
We are proud to announce that alfred is now available on PyPi. Because there already exists a package named “alfred”, we decided to change the name to “alfred3” in celebration of the recent port to Python 3.
Alfred3 can now be installed via pip:
pip install alfred3
When alfred is installed via pip, you must change all imports in your
script.pyandrun.pyto the new name.
Changed¶
Changed name to alfred3 (see above).
From now on, we will generally be using the changelog format recommended by Keep a Changelog
In the course of this change, we changed the name of the former
NEWS.mdtoCHANGELOG.md.
alfred v1.0.7¶
Security improvements¶
We further increased data protection and data security through an improved handling of access to the alfred database from inside web experiments deployed via mortimer.
Updated handling of local experiments: You can now specify an optional
auth_sourceparameter in themongo_saving_agentsection inconfig.conf. The parameter will be passed to theauthSourceparameter ofpymongo.MongoClientin the initialisation of the saving agent. This allows you to use database accounts that user other databases than “admin” for authentication, which offers greater security.
Smaller changes¶
Disabled the logging of debug messages for the
Page.on_showing()method. This led to overcrowded logs.
alfred v1.0.6¶
Encryption¶
In your script.py, you can now use symmetric encryption to encrypt your data. The encryption is performed with an instance of
cryptography.fernet.Fernet, using a safe, user-specific unique key generated by mortimer (v0.4.4+).Encryption: Encrypt data of types
str,int, andfloatviaalfred.Experiment.encrypt(). The method will return an encrypted version of your data, converted to string.Decryption: Decrypt data of types
strorbytesviaalfred.Experiment.decrypt(). The method will return a decrypted version of your data, converted to string.
NOTE that the saving agent will automatically save all data collected by elements (after the
on_hiding()method is executed). You will need to encrypt data before they are saved in order to secure your data in the database.For offline testing, the Fernet instance will be initialized with the key
OnLhaIRmTULrMCkimb0CrBASBc293EYCfdNuUvIohV8=. IMPORTANT: This key is public. Encrypted data in local (e.g., offline) experiments is not safe. This functionality is provided exclusively for testing your experiment before uploading to mortimer and running.
Smaller changes and Bugfixes¶
Pages now have a getter method for their experiment, i.e. you can access the experiment via
Page.experiment, if the page has been added to an experiment instance at the time the method is called.Fixed the display of experimenter messages (e.g. a message that informs the participant about a minimum display time, if he or she tries to move to the next page too early)
alfred v1.0.5¶
Bugfixes¶
fixed #37
Minor changes¶
rename
PageController.change_to_finished_section: This was a missed function call from the old naming scheme. Generally, it will not affect the user in most cases, but it still exists as a deprecated function, logging a warning now.
Bugfixes¶
alfred v1.0.4¶
Bugfixes¶
This includes a hotfix for an issue with ALfred v1.0.3.
Minor changes¶
Local saving agent now checks, whether the path given in config.conf is absolute. If not, the agent treats it as a relative path, relative to the experiment directory.
Alfred now saves its the version number alongside each saved dataset, so that the used version can be identified.
alfred v1.0.2¶
Bugfixes¶
Fixed a bug in
localserver.pythat caused trouble for videos implemented viaalfred.element.WebVideoElementin Safari (wouldn’t play at all) and Chrome (forward/backward wouldn’t work)
Other changes¶
alfred.element.WebVideoElement:New parameter
source: A filepath or url that points to the video (str).New parameter
sources_list: A list of filepaths and/or urls that point to the video, use this if you want to include fallback options in different formats or from different sources (listofstrelements).The parameters
mp4_path,mp4_url,ogg_path,ogg_url,web_m_path, andweb_m_urlare replaced bysource. They still work, but will now log a deprecation warning.New parameter
muted=False: IfTrue, the video will play with muted sound by default.The parameter
widthnow defaults towidth=720.Disabled the right-click context menu for videos included via
alfred.element.WebVideoElementDisabled video download for videos implemented via
alfred.element.WebVideoElement(was only possible in Chrome).
Pagegets a new parameterrun_on_showing, which defaults torun_on_showing='once'. This means, by default a Page executes theon_showingmethod only when it is shown for the first time. This behavior can be altered by setting the new parameter torun_on_showing='always'. The latter can lead to duplicate elements on a page, if a subject goes backward inside an experiment, which will be unwanted behavior in most cases.
alfred v1.0.1¶
Bugfixes¶
Fixed a bug that caused a mixup with filepaths for web experiments hosted with mortimer.
alfred v1.0¶
Breaking changes¶
Port to Python 3¶
One of the most important changes for us is the port from Python 2.7 to Python 3, which will ensure ongoing support for the coming years.
You can find key differences listed here: https://docs.python.org/3.0/whatsnew/3.0.html
All strings in Python 3 are unicode by default. In Python 2.7, strings with umlauts like ä, ö or ü needed to be preceded by a u to turn them into unicode-strings:
u"Example strüng.". This often lead to unnecessary errors and is not necessary anymore.Printing works a little differently. You used to be able to print output to the console with a command like
print "this string". This syntax is now deprecated and will throw an error. From now on, you need to use the print statement like any normal function:print("this string").
New class names¶
PagereplacesWebCompositeQuestionSectionreplacesQuestionGroupSegmentedSectionreplacesSegmentedQGHeadOpenSectionrepladcesHeadOpenQGThese changes should clarify the functionality of the corresponding classes.
Switch from lowerCamelCase to underscore_case¶
Throughout alfreds complete code base, we switched from
lowerCamelCasetounderscore_case.ATTENTION: This affects almost every line of code!This change reflects our effort to adhere to PEP 8 Styleguide (PEP - click for more info). Some excerpts:
Class names should normally use the CapWords convention.
Function names should be lowercase, with words separated by underscores as necessary to improve readability.
Variable names follow the same convention as function names.
Method names and instance variables: Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.
New names for existing features¶
Page.on_showing()replacesWebCompositeQuestion.onShowingWidget()(Alfred v0.2b5 name).Page.append()replacesWebCompositeQuestion.addElement()andWebCompositeQuestion.addElements()(Alfred v0.2b5 names).Page.get_page_data()is a new shortcut forWebCompositeQuestion._experiment.dataManager.findExperimentDataByUid()(Alfred v0.2b5 name), a method for accessing data from a previous page inside anon_showinghook.Section.append()replacesQuestionGroup.appendItem()andQuestionGroup.appendItems()(Alfred v0.2b5 names).Experiment.append()replacesExperiment.questionController.appendItem()andExperiment.questionController.appendItems()(Alfred v0.2b5 names).Experiment.change_final_page()is a new shortcut forExperiment.pageController.appendItemToFinishQuestion()(Alfred v0.2b5 name), a method for changing the final page of on exp.
Experiment metadata¶
There is a new section
[metadata]inconfig.conf, which includes the following information:title: The experiment title (previously called experiment name)author: The experiment authorversion: The experiment versionexp_id: The experiment ID (IMPORTANT: This ID is used to identify your experiment data, if you set up a local alfred experiment to save data to the mortimer database. It is not used, if you deploy your experiment as a web experiment via mortimer.)
alfred.Experimentno longer takes the argumentsexpType,expNameandexpVersion. Instead, these metadata are now defined in theconfig.conf, section[metadata].To process metadata in mortimer, the following changes need to be implemented in
script.py:def generate_experiment(config=None)(the function gets a new parameterconfig, which defaults toNone)exp = Experiment(config=config)(the experiment should be initialized with the parameterconfig, defaulting toconfig, which gets handed down from thegenerate_experimentfunction.)
File import¶
Importing a file from the project directory now always needs to take place within the
generate_experiment()function. This is necessary for compatibility with the newest version of mortimer. This way, we can handle multiple resources directories.
New Features¶
New recommended script.py style¶
Removed the need to define a script class (
class Script(object)), saving one layer of indentationRemoved the need to end a script with
generate_experiment = Script().generate_experimentRemoved the need to define
expNameandexpVersioninside scriptRecommended style: Define a new class for every page in your experiment. This has a couple of advantages:
No difference between defining static pages and dynamic pages anymore. This lowers the hurdle for creating dynamic experiments.
Separation of experiment structure and experiment content is enhanced, which should clarify the
script.pyCode reuse is facilitated (Pages can be reused)
Example:
# -*- coding:utf-8 -*-
from alfred import Experiment
from alfred.page import Page
import alfred.element as elm
import alfred.section as sec
class HelloWorld(Page):
def on_showing(self):
hello_text = elm.TextEntryElement('Please enter some text.')
self.append(hello_text)
def generate_experiment(self, config):
exp = Experiment(config=config)
hello_world = HelloWorld(title='Hello, world!')
main = sec.Section()
main.append(hello_world)
exp.append(main)
return exp
Increased security for local experiments¶
We implemented a three-step process to access database login data. The first two options make it much safer to share your code, e.g.on the OSF, because you don’t have to worry about accidentally sharing secrets anymore.
Provide login data in environment variables (new, recommended)
Provide encrypted login data in
config.conf(new, recommended)Provide raw login data in
config.conf(not recommended, use only for testing)
If your databse is correctly equipped with a valid commercial SSL certificate, you can now set the option
use_ssl = truein the section[mongo_saving_agent]of yourconfig.confto enable a secure connection via SSL. You can also use self-signed SSL certificates, if you set the optionca_file_pathto the file path of your Certificate Authority (CA) public key file (often a .pem file).
Page.values¶
Page.valuesis a dictionary that serves as a container for pages. You can use it for example to create pages using loops and if-statements. More on how to use it can soon be found in the wiki. It is a special dictionary that allows for element access (reading and writing) via dot-notation.
Example:
# (imports)
class Welcome(Page):
def on_showing(self):
text01 = TextElement(self.values.text01, name='text01')
self.append(text01)
def generate_experiment(self, config=None):
exp = Experiment(config=config)
page = Welcome(title='page01', uid='page01')
page.values.text01 = 'text01'
exp.append(page)
return exp
Deprecated¶
| Deprecated function (alfred v0.2b5 name) | Replaced by |
| ————- | ————- |
| WebCompositeQuestion.onShowingWidget() | Page.on_showing() |
| WebCompositeQuestion.onHidingWidget() | Page.on_hiding() |
| WebCompositeQuestion.addElement() | Page.append() |
| WebCompositeQuestion.addElements() | Page.append() |
| QuestionGroup.appendItem() | Section.append() |
| QuestionGroup.appendItems() | Section.append() |
| Experiment.questionController.appendItem() | Experiment.append() |
| Experiment.questionController.appendItems() | Experiment.append() |
Bug fixes and other changes¶
Improved handling of browser commands. In web experiments, subjects used to be able to cause trouble by using the browser controls (forward, backward, refresh) instead of the experiment controls at the bottom of the page to move through an experiment. In some cases, this could render the subject’s data unusable. Now, when a subject uses the browser controls, Alfred will always return the current state of the experiment. This way, no more data should be lost.
Fixed a saving agent bug. When quickly moving through an experiment, the saving agent sometimes didn’t complete it’s tasks correctly and basically crashed. This does not happen anymore.
Removed features¶
No more pure QT experiments. We completely removed pure QT experiments from the framework. Those have recently seen very little use and have some drawbacks compared to web experiments and qt-webkit (qt-wk) experiments.