How to run script from different startpoint depending on inputted value?

Question:

So I am creating an experiment in python in which there are several tasks. I want to create a function which can start the experiment from a different start point if the experiment is quit mid-way through e.g., after 2 tasks I want it to start from the third.

When the run function (for the entire experiment) is called, you can pass ‘restart=True’ which then calls a restart function:

    def __init__(self, portname, restart=False):
        self.__port_name = portname
        self.__path = '/Users/emilia/Documents/Dementia task piloting/Lumo'
        self.__restart = restart

    def __restart(self):
        if self.__restart:
            restart_point = {'Task to restart from': ''}
            dlg = gui.DlgFromDict(dictionary=restart_point, sortKeys=False, title='Where do you want to restart from?')
            if not dlg.OK:
                print("User pressed 'Cancel'!")
                core.quit()
            return restart_point['Task to restart from']
        else:
            return None

    def run(self):
        start_point = self.__restart()
        if start_point:  # TODO: how to run from start point
            pass
        else: # Run tasks
            auditory_exp = self.__auditory_staircase(5)
            object_recognition_exp = self.__object_recognition()
            self.__resting_state()
            simple_motor_exp = self.__simple_motor_task()
            naturalistic_motor_exp = self.__naturalistic_motor_task()
            self.__end_all_experiment()

In the final run function which calls all of the tasks (the functions of which aren’t shown here), how do I get it to skip to the task name inputted into the dialogue box should restart=True? Thank you!

Asked By: sallicap

||

Answers:

As all your tasks are called subsequently, a simple way would be to put your tasks in a list and iterate over it:

import random

class Experiment:
    def auditory_staircase(self, i: int):
        print(f"Run: Auditory Staircase (i: {i})")

    def object_recognition(self):
        print(f"Run: Object Recognition")

    def resting_state(self):
        print(f"Run: Resting State")

    def load(self, taskname: str):
        # If you need to load previous results
        print(f"Load: {taskname}")

    def restart(self):
        """ Selects a random start point """
        return random.choice([None, "Auditory Staircase", "Object Recognition", "Resting State"])

    def run(self): 
        # List of the tasks with function, arguments and keyword-arguments
        tasks = [
            ("Auditory Staircase", self.auditory_staircase, [5], {}),
            ("Object Recognition", self.object_recognition, [], {}),
            ("Resting State", self.resting_state, [], {}),
        ]

        start_from = self.restart()
        print(f"restart() returned: {start_from}")
        if start_from == None:
            start_from = tasks[0][0]

        # Iterate over the tasks, and either load previous result or start them
        started = False
        for taskname, fn, args, kwargs in tasks:
            if taskname == start_from:
                started = True

            if started:
                fn(*args, **kwargs)
            else:
                self.load(taskname)


# Run 10 experiments
e = Experiment()
for i in range(10):
    print(f"---- Run {i} ----")
    e.run()
    print("")

This code runs 10 different experiments, each with a random start_point. The output looks like this:

---- Run 0 ----
restart() returned: Auditory Staircase
Run: Auditory Staircase (i: 5)
Run: Object Recognition
Run: Resting State

---- Run 1 ----
restart() returned: Resting State
Load: Auditory Staircase
Load: Object Recognition
Run: Resting State

---- Run 2 ----
restart() returned: None
Run: Auditory Staircase (i: 5)
Run: Object Recognition
Run: Resting State

...

I included some code to load the results from the previous run. If you don’t need that, you can skip that of course.

Answered By: johannesmik
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.