6.2.1 Studies and Steps
On this page:
study?
make-study
run-study
6.2.1.1 Study variables
defvar
defvar*
defvar/  instance
defvar*/  instance
6.2.1.2 Steps
step?
make-step
make-step/  study
next
done
6.2.1.3 Step Widgets
button
form
skip
6.2.1.4 Study loops
for/  study
6.2.1 Studies and Steps🔗

 (require congame/components/study) package: congame-core

procedure

(study? v)  boolean?

  v : any/c
Returns #t when v is a study.

procedure

(make-study name    
  steps    
  [#:requires requires    
  #:provides provides    
  #:transitions transitions    
  #:view-handler view-handler    
  #:failure-handler failure-handler])  study?
  name : string?
  steps : (listof step?)
  requires : (listof symbol?) = null
  provides : (listof symbol?) = null
  transitions : (or/c #f (hash/c symbol? any/c)) = #f
  view-handler : (or/c #f (-> request? response?)) = #f
  failure-handler : (or/c #f (-> step? any/c step-id/c)) = #f
Creates a study that can be run by run-study. The name argument is used in debugging and in the admin interface. Any step that is part of the study has to be listed in steps.

The #:transitions argument has to be a transition-graph that provides all the transitions between the steps. See transition-graph for details.

procedure

(run-study s [req #:bindings bindings])  any/c

  s : study?
  req : request? = (current-request)
  bindings : (hash/c symbol? any/c) = (hasheq)
Runs the study s under req with bindings.

6.2.1.1 Study variables🔗

syntax

(defvar id)

syntax

(defvar* id global-id)

Defines a study variable with participant scope bound to id. The study variable can be accessed inside the study steps using id and updated with (set! id expr).

The value of the study variable will be stored in the Congame server database under the current study → instance → participant.

Study variables created with defvar* will additionally be visible to any child studies (see defstep/study).

Important: when using defvar*, you must provide a second identifier global-id and manually ensure it is distinct from any identifiers that may be used in child studies. This prevents child studies that may be using the same identifier names from accidentally overwriting your parent study’s variable.

syntax

(defvar/instance ...)

syntax

(defvar*/instance ...)

Like defvar and defvar*, but for creating study variables with instance scope that is, the stored value is shared by all participants in the study instance.

6.2.1.2 Steps🔗

procedure

(step? v)  boolean?

  v : any/c
Returns #t when v is a step.

procedure

(make-step id    
  handler    
  [transition    
  #:view-handler view-handler    
  #:for-bot bot-handler])  step?
  id : symbol?
  handler : (-> xexpr?)
  transition : transition/c = (lambda () next)
  view-handler : (or/c #f (-> request? response?)) = #f
  bot-handler : (or/c #f procedure?) = #f

procedure

(make-step/study id    
  s    
  [transition    
  #:require-bindings require-bindings    
  #:provide-bindings provide-bindings])  step?
  id : symbol?
  s : study?
  transition : transition/c = (lambda () next)
  require-bindings : (listof binding/c) = null
  provide-bindings : (listof binding/c) = null
Creates a step that executes s when reached.

The #:require-bindings argument maps identifiers required by s to identifiers available in the current study context if the name is different – otherwise it assumes that required identifers share names and attempts to set them accordingly.

The #:provide-bindings argument maps identifiers in the current study that should be mapped to some subset of the identifiers provided by s upon completion. When #:provide-bindings is null?, no values are assigned.

For example:

(make-step/study
  'required-tasks
  task-study
  #:require-bindings '([n task-treatment])
  #:provide-bindings '([root-success? success?]))

Here, n in task-study will take on the value of task-treatment, and after running, root-success? will be assigned the value of success? in the parent.

canary

next : any/c

canary

done : any/c

Special values that can be used as transition results to cause a study to transition to the next step or to the end of the study, respectively.

6.2.1.3 Step Widgets🔗

procedure

(button action    
  label    
  [#:id id    
  #:to-step-id to-step-id])  xexpr?
  action : (-> void?)
  label : xexpr?
  id : string? = ""
  to-step-id : (or/c #f symbol?) = #f
Renders a button with the given label that executes action when pressed. After the action is executed, moves the participant to the step named by to-step-id or the next step if to-step-id is #f.

The #:id argument is useful for identifying the button within bot handlers.

procedure

(form f    
  action    
  render    
  [#:id id    
  #:enctype enctype])  xexpr?
  f : form?
  action : (-> void?)
  render : (-> (widget-renderer/c) xexpr?)
  id : string? = ""
  enctype : string? = "multipart/form-data"
Renders the form represented by f using render and executes action on successful submission, then continues to the next step in the study.

The #:id argument is the same as for button.

procedure

(skip [to-step-id])  void?

  to-step-id : symbol? = #f
Skips to the step named by to-step-id or the next step in the study if to-step-id is #f.

6.2.1.4 Study loops🔗

 (require congame/components/for-study)
  package: congame-core

syntax

(for/study [#:substudies]
           [#:requires requires]
           [#:provides provides]
           (for-clause ...)
           body-or-break ... body)
 
  requires : (listof symbol?)
  provides : (listof symbol?)
Iterates like for but each result of the last body accumulated into a list of steps, which are passed to make-study to produce a study.

Use for/study for quickly building studies with many steps that differ in only a few places.

(for/study ([phase (in-list '("Setup" "Activation" "Tear-down"))])
  (page
    (haml
      (:h1 phase " Phase")
      (:p "...")
      (button void "Next"))))