Examples

You can find all examples on this page in the doc/examples folder.

Inter-temporal Choice Task

This is the exact same example as on the front page.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import pygame
from pyparadigm.surface_composition import *
from pyparadigm.misc import empty_surface, display, init
from pyparadigm.eventlistener import EventListener

import json

# Scroll to the bottom, and start reading in the main() ;)

def offer_box(title, amount):
    # Creates a border around a vertical layout containing 2 cells, where the
    # lower one has twice the size of the upper one (layout children are
    # automatically wrapped in LLItems with relative_size=1). Both Boxes are
    # filled with text, wich is centered in its parent area.
    return Border()(
            LinLayout("v")(
                Text(title, Font(size=50)),
                LLItem(2)(Text(f"{amount}€", Font(size=50, bold=True)))
            )
        )


def make_offer(now, later, delay):
    # Create pygame.Surface with a white background.
    # The LinLayout splits the available space into (in this case)
    # equally sized horizontally aligned parts. 80% of the available
    # space of each part is used to display a offer box.
    return compose(empty_surface(0xFFFFFF), LinLayout("h"))(
        Padding.from_scale(0.8)(offer_box("Now", now)),
        Padding.from_scale(0.8)(offer_box(f"In {delay} days", later)),
    )


def make_feedback(amount, delay):
    # creates a pygame.Surface which only contains the text message
    msg = f"{amount}€ " + ("now" if delay == 0 else f"in {delay} days")
    return compose(empty_surface(0xFFFFFF))(Text(msg, Font(size=50)))


def main():
    # initiate a window with a resolution of 800 x 600 pixels
    init((800, 600))
    # alternatively, to create a full screen, hardware accelrated window, you
    # could use:
    # init((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE | pygame.DOUBLEBUF)

    # Create an Eventlistener object
    event_listener = EventListener()

    # Initiate the data for the paradigm, and create 2 lists to store 
    # the results
    immediate_offers = ([10] * 3) + ([20] * 3) + ([30] * 3)
    delays = [10, 20, 30] * 3
    delayed_offers = [delay + im_offer 
        for delay, im_offer in zip(delays, immediate_offers)]
    chosen_amounts = []
    chosen_delays = []

    # Execute the paradigm
    for im_offer, del_offer, delay in zip(immediate_offers, delayed_offers, delays):
        # display the offer
        display(make_offer(im_offer, del_offer, delay))

        # wait for a decision in form of the left or right arrow-key
        key = event_listener.wait_for_keys([pygame.K_LEFT, pygame.K_RIGHT])

        # store results according to decision
        if key == pygame.K_LEFT:
            chosen_amounts.append(im_offer)
            chosen_delays.append(0)
        else:
            chosen_amounts.append(del_offer)
            chosen_delays.append(delay)
        
        # display a feedback for 2 seconds
        display(make_feedback(chosen_amounts[-1], chosen_delays[-1]))
        event_listener.wait_for_seconds(2)

    # save results to a json File
    with open("results.json", "w") as file:
        json.dump({"amount": chosen_amounts, "delay": chosen_delays}, file)

        
if __name__ == '__main__':
    main()

Flashing Checkerboard

This example just alternates the two stimuli with frequency of 2Hz. To make sure, that the interpreter finds the stimuli cd into the examples folder, and execute it from there.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import pygame
from pyparadigm.misc import init, display, empty_surface
from pyparadigm.surface_composition import compose, Surface, Text, Font
from pyparadigm.eventlistener import EventListener
from functools import lru_cache
from itertools import cycle

def render_frame(screen, frame):
    # This time we dont use :py:func:`misc.display` and instead draw directly
    # onto the screen, and call flip() then to display it. Usually we would want
    # to generate a screen with a function (with lru_cache), and then use
    # :py:func:`misc.display` to blit the different screens. This way every
    # screen is only computed once. This time though, no screens are computed,
    # it is simply displaying an existing image, and no screens are reused.
    compose(screen)(Surface(scale=1)(frame))
    pygame.display.flip()


def main():
    # we want to display the two states with 2Hz, therefore the timeout is 1/2s
    timeout = 0.5
    # initialize a window, and get a reference to the pygame.Surface
    # representing the screen.
    screen = init((1024, 800))
    # Load the frames. When loading a pygame.Surface from a file, you should
    # always call convert() on it, this will change the image format to optimize
    # performance. If you have an image that uses transparent pixels, use
    # convert_alpha() instead.
    # We use itertools.cycle to get an iterator that will alternate between the
    # images, see the python-doc (https://docs.python.org/3/library/itertools.html)
    frames = cycle([pygame.image.load(f"checkerboard_{i}.png").convert() 
                        for i in range(2)])
    # Create an EventListener object. No additional handlers needed here.
    event_listener = EventListener()
    # Display an initial text
    display(compose(empty_surface(0xFFFFFF))(Text(
        """Press Return to start.

        Press again to end.""", Font(size=60))))
    # Wait for the return key
    event_listener.wait_for_n_keypresses(pygame.K_RETURN)
    key = None
    # Repeat until return is pressed again
    while key == None:
        # display one of the two checkerboard images
        render_frame(screen, next(frames))
        # wait for timeout seconds for RETURN to be pressed. If RETURN is
        # pressed :py:meth:`EventListener.wait_for_keys` will return
        # pygame.K_RETURN otherwise it will return NONE
        key = event_listener.wait_for_keys([pygame.K_RETURN], timeout)
    


if __name__ == '__main__':
    main()