role_simulator

Class to define the role object within the simulation. The role is defined by its name (name), the amount of resources available (capacity), and the schedule assigned to it (calendar).

Each role needs to be defined within the json file in the following format. The example describes Role 2, Ellen and Sue, who work Monday through Saturday, from 8 a.m. to 7 p.m.

    "resource": {
        ........
        "name_of_role": {
            "resources": #List of resources,
            "calendar": {
                "days": #List of working days of the role,
                        #given as integer 0 means Sunday and 6 means Saturday.
                "hour_min": #the hour of the start of the working day,
                "hour_max": #the hour of the end of the working day
            }
        }
        ........
    }
    "Role 2": {
        "resources": ["Ellen", "Sue"],
        "calendar": {
            "days": [1, 2, 3, 4, 5, 6],
            "hour_min": 8,
            "hour_max": 19
        }
    }

Finally, in the simulation parameters file, we have to indicate the role assigned to the execution of each activity. (Here to view complete examples)

    "resource_table": [
        {
            "role": "Role 1",
            "task": "A_SUBMITTED"
        },
        {
            "role": "Role 2",
            "task": "A_PARTLYSUBMITTED"
        }
    ]
  1'''
  2Class to define the role object within the simulation.
  3The role is defined by its name (*name*), the amount of resources available (*capacity*),
  4and the schedule assigned to it (*calendar*).
  5
  6Each role needs to be defined within the json file in the following format.
  7The example describes *Role 2*, Ellen and Sue, who work Monday
  8through Saturday, from 8 a.m. to 7 p.m.
  9```shell
 10    "resource": {
 11        ........
 12        "name_of_role": {
 13            "resources": #List of resources,
 14            "calendar": {
 15                "days": #List of working days of the role,
 16                        #given as integer 0 means Sunday and 6 means Saturday.
 17                "hour_min": #the hour of the start of the working day,
 18                "hour_max": #the hour of the end of the working day
 19            }
 20        }
 21        ........
 22    }
 23```
 24
 25```json
 26    "Role 2": {
 27        "resources": ["Ellen", "Sue"],
 28        "calendar": {
 29            "days": [1, 2, 3, 4, 5, 6],
 30            "hour_min": 8,
 31            "hour_max": 19
 32        }
 33    }
 34```
 35Finally, in the simulation parameters file, we have to indicate the role assigned to the execution of each activity.
 36(Here to view complete examples)
 37
 38```json
 39    "resource_table": [
 40        {
 41            "role": "Role 1",
 42            "task": "A_SUBMITTED"
 43        },
 44        {
 45            "role": "Role 2",
 46            "task": "A_PARTLYSUBMITTED"
 47        }
 48    ]
 49```
 50
 51'''
 52from datetime import timedelta
 53import simpy
 54
 55
 56class RoleSimulator(object):
 57
 58    def __init__(self, env: simpy.Environment, name: str, capacity, calendar: dict):
 59        self._env = env
 60        self._name = name
 61        self._resources_name = capacity
 62        self._capacity = capacity if type(capacity) == float else len(capacity)
 63        self._calendar = calendar
 64        self._resource_simpy = simpy.Resource(env, self._capacity)
 65        self._queue = []
 66
 67    def _get_name(self):
 68        return self._name
 69
 70    def _get_capacity(self):
 71        return self._capacity
 72
 73    def _get_resource(self):
 74        return self._resource_simpy
 75
 76    def _get_calendar(self):
 77        return self._calendar
 78
 79    def release(self, request):
 80        """
 81        Method to release the role resource that was used to perform the activity.
 82        """
 83        self._resource_simpy.release(request)
 84
 85    def request(self):
 86        """
 87        Method to require a resource of the role needed to perform the activity.
 88        """
 89        self._queue.append(self._resource_simpy.queue)
 90        return self._resource_simpy.request()
 91
 92    def _check_day_work(self, timestamp):
 93        return True if (timestamp.weekday() in self._calendar['days']) else False
 94
 95    def _check_hour_work(self, timestamp):
 96        return True if (self._calendar['hour_min'] <= timestamp.hour < self._calendar['hour_max']) else False
 97
 98    def _define_stop_weekend(self, timestamp):
 99        monday = 7 - timestamp.weekday()
100        new_start = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) + timedelta(days=monday)
101        return (new_start-timestamp).total_seconds()
102
103    def _define_stop_week(self, timestamp):
104        if timestamp.hour < self._calendar['hour_min']:
105            stop = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) - timestamp
106        else:
107            new_day = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) + timedelta(days=1)
108            stop = new_day - timestamp
109        return stop.total_seconds()
110
111    def to_time_schedule(self, timestamp):
112        """
113            Method to check the schedule of the requested resource and
114            eventually it returns the time to wait before executing the activity.
115        """
116        if not self._check_day_work(timestamp):
117            stop = self._define_stop_weekend(timestamp)
118        elif not self._check_hour_work(timestamp):
119            stop = self._define_stop_week(timestamp)
120        else:
121            stop = 0
122        return int(stop)
123
124    def _split_week(self, timestamp, duration):
125        before = (timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0) - timestamp).seconds
126        stop = self._define_stop_week(timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0))
127        if not self._check_day_work(timestamp + timedelta(seconds=before) + timedelta(seconds=stop)):
128            stop += self._define_stop_weekend(timestamp + timedelta(seconds=before + stop))
129        after = duration - before
130        return before, stop, after
131
132    def _split_weekend(self, timestamp, duration):
133        before = (timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0) - timestamp).total_seconds
134        stop = self._define_stop_weekend(timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0))
135        after = duration - before
136        return before, stop, after
137
138    def _check_duration(self, timestamp, duration):
139        time_to_complete = timestamp + timedelta(seconds=duration)
140        before = duration
141        stop = after = 0
142        if not self._check_hour_work(time_to_complete):
143            if self._check_day_work(time_to_complete) in self._calendar['days']:
144                before, stop, after = self._split_week(timestamp, duration)
145            else:
146                before, stop, after = self._split_weekend(timestamp, duration)
147        return before, stop, after
148
149    def _define_timework(self, timestamp, duration):
150        stop_pre = self.to_time_schedule(timestamp)
151        before, stop, after = self._check_duration(timestamp + timedelta(seconds=stop_pre), duration)
152        return stop_pre, before + stop + after
153
154    def _get_resources_name(self):
155        choiced = self._resources_name[0]
156        self._resources_name.remove(choiced)
157        return choiced
158
159    def _release_resource_name(self, resource):
160        self._resources_name.append(resource)
class RoleSimulator:
 57class RoleSimulator(object):
 58
 59    def __init__(self, env: simpy.Environment, name: str, capacity, calendar: dict):
 60        self._env = env
 61        self._name = name
 62        self._resources_name = capacity
 63        self._capacity = capacity if type(capacity) == float else len(capacity)
 64        self._calendar = calendar
 65        self._resource_simpy = simpy.Resource(env, self._capacity)
 66        self._queue = []
 67
 68    def _get_name(self):
 69        return self._name
 70
 71    def _get_capacity(self):
 72        return self._capacity
 73
 74    def _get_resource(self):
 75        return self._resource_simpy
 76
 77    def _get_calendar(self):
 78        return self._calendar
 79
 80    def release(self, request):
 81        """
 82        Method to release the role resource that was used to perform the activity.
 83        """
 84        self._resource_simpy.release(request)
 85
 86    def request(self):
 87        """
 88        Method to require a resource of the role needed to perform the activity.
 89        """
 90        self._queue.append(self._resource_simpy.queue)
 91        return self._resource_simpy.request()
 92
 93    def _check_day_work(self, timestamp):
 94        return True if (timestamp.weekday() in self._calendar['days']) else False
 95
 96    def _check_hour_work(self, timestamp):
 97        return True if (self._calendar['hour_min'] <= timestamp.hour < self._calendar['hour_max']) else False
 98
 99    def _define_stop_weekend(self, timestamp):
100        monday = 7 - timestamp.weekday()
101        new_start = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) + timedelta(days=monday)
102        return (new_start-timestamp).total_seconds()
103
104    def _define_stop_week(self, timestamp):
105        if timestamp.hour < self._calendar['hour_min']:
106            stop = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) - timestamp
107        else:
108            new_day = timestamp.replace(hour=self._calendar['hour_min'], minute=0, second=0) + timedelta(days=1)
109            stop = new_day - timestamp
110        return stop.total_seconds()
111
112    def to_time_schedule(self, timestamp):
113        """
114            Method to check the schedule of the requested resource and
115            eventually it returns the time to wait before executing the activity.
116        """
117        if not self._check_day_work(timestamp):
118            stop = self._define_stop_weekend(timestamp)
119        elif not self._check_hour_work(timestamp):
120            stop = self._define_stop_week(timestamp)
121        else:
122            stop = 0
123        return int(stop)
124
125    def _split_week(self, timestamp, duration):
126        before = (timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0) - timestamp).seconds
127        stop = self._define_stop_week(timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0))
128        if not self._check_day_work(timestamp + timedelta(seconds=before) + timedelta(seconds=stop)):
129            stop += self._define_stop_weekend(timestamp + timedelta(seconds=before + stop))
130        after = duration - before
131        return before, stop, after
132
133    def _split_weekend(self, timestamp, duration):
134        before = (timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0) - timestamp).total_seconds
135        stop = self._define_stop_weekend(timestamp.replace(hour=self._calendar['hour_max'], minute=0, second=0))
136        after = duration - before
137        return before, stop, after
138
139    def _check_duration(self, timestamp, duration):
140        time_to_complete = timestamp + timedelta(seconds=duration)
141        before = duration
142        stop = after = 0
143        if not self._check_hour_work(time_to_complete):
144            if self._check_day_work(time_to_complete) in self._calendar['days']:
145                before, stop, after = self._split_week(timestamp, duration)
146            else:
147                before, stop, after = self._split_weekend(timestamp, duration)
148        return before, stop, after
149
150    def _define_timework(self, timestamp, duration):
151        stop_pre = self.to_time_schedule(timestamp)
152        before, stop, after = self._check_duration(timestamp + timedelta(seconds=stop_pre), duration)
153        return stop_pre, before + stop + after
154
155    def _get_resources_name(self):
156        choiced = self._resources_name[0]
157        self._resources_name.remove(choiced)
158        return choiced
159
160    def _release_resource_name(self, resource):
161        self._resources_name.append(resource)
RoleSimulator(env: simpy.core.Environment, name: str, capacity, calendar: dict)
59    def __init__(self, env: simpy.Environment, name: str, capacity, calendar: dict):
60        self._env = env
61        self._name = name
62        self._resources_name = capacity
63        self._capacity = capacity if type(capacity) == float else len(capacity)
64        self._calendar = calendar
65        self._resource_simpy = simpy.Resource(env, self._capacity)
66        self._queue = []
def release(self, request):
80    def release(self, request):
81        """
82        Method to release the role resource that was used to perform the activity.
83        """
84        self._resource_simpy.release(request)

Method to release the role resource that was used to perform the activity.

def request(self):
86    def request(self):
87        """
88        Method to require a resource of the role needed to perform the activity.
89        """
90        self._queue.append(self._resource_simpy.queue)
91        return self._resource_simpy.request()

Method to require a resource of the role needed to perform the activity.

def to_time_schedule(self, timestamp):
112    def to_time_schedule(self, timestamp):
113        """
114            Method to check the schedule of the requested resource and
115            eventually it returns the time to wait before executing the activity.
116        """
117        if not self._check_day_work(timestamp):
118            stop = self._define_stop_weekend(timestamp)
119        elif not self._check_hour_work(timestamp):
120            stop = self._define_stop_week(timestamp)
121        else:
122            stop = 0
123        return int(stop)

Method to check the schedule of the requested resource and eventually it returns the time to wait before executing the activity.