diff --git a/ciw/arrival_node.py b/ciw/arrival_node.py index 32104953..a25eeb72 100644 --- a/ciw/arrival_node.py +++ b/ciw/arrival_node.py @@ -30,8 +30,8 @@ def __init__(self, simulation): self.number_accepted_individuals_per_class = {clss: 0 for clss in self.simulation.network.customer_class_names} self.system_capacity = self.simulation.network.system_capacity self.event_dates_dict = { - nd + 1: {clss: False for clss in self.simulation.network.customer_class_names - } for nd in range(self.simulation.network.number_of_nodes) + node + 1: {clss: False for clss in self.simulation.network.customer_class_names + } for node in range(self.simulation.network.number_of_nodes) } def initialise(self): @@ -66,12 +66,12 @@ def find_next_event_date(self): minnd = None minclss = None mindate = float("Inf") - for nd in self.event_dates_dict: - for clss in self.event_dates_dict[nd]: - if self.event_dates_dict[nd][clss] < mindate: - minnd = nd + for node in self.event_dates_dict: + for clss in self.event_dates_dict[node]: + if self.event_dates_dict[node][clss] < mindate: + minnd = node minclss = clss - mindate = self.event_dates_dict[nd][clss] + mindate = self.event_dates_dict[node][clss] self.next_node = minnd self.next_class = minclss self.next_event_date = mindate @@ -79,7 +79,7 @@ def find_next_event_date(self): def have_event(self): """ Finds a batch size. Creates that many Individuals and send - them to the relevent node. Then updates the event_dates_dict. + them to the relevant node. Then updates the event_dates_dict. """ batch = self.batch_size(self.next_node, self.next_class) for _ in range(batch): @@ -114,25 +114,25 @@ def initialise_event_dates_dict(self): Initialises the next event dates dictionary with random times for each node and class. """ - for nd in self.event_dates_dict: - for clss in self.event_dates_dict[nd]: - if self.simulation.inter_arrival_times[nd][clss] is not None: - self.event_dates_dict[nd][clss] = self.inter_arrival(nd, clss) + for node in self.event_dates_dict: + for clss in self.event_dates_dict[node]: + if self.simulation.inter_arrival_times[node][clss] is not None: + self.event_dates_dict[node][clss] = self.inter_arrival(node, clss) else: - self.event_dates_dict[nd][clss] = float("inf") + self.event_dates_dict[node][clss] = float("inf") - def inter_arrival(self, nd, clss): + def inter_arrival(self, node, customer_class): """ Samples the inter-arrival time for next class and node. """ - return self.simulation.inter_arrival_times[nd][clss]._sample(t=self.simulation.current_time) + return self.simulation.inter_arrival_times[node][customer_class]._sample(t=self.simulation.current_time) - def batch_size(self, nd, clss): + def batch_size(self, node, customer_class): """ Samples the batch size for next class and node. Raises error if a positive integer is not sampled. """ - batch = self.simulation.batch_sizes[nd][clss]._sample(t=self.simulation.current_time) + batch = self.simulation.batch_sizes[node][customer_class]._sample(t=self.simulation.current_time) if isinstance(batch, int) and batch >= 0: return batch raise ValueError("Batch sizes must be positive integers.") diff --git a/ciw/auxiliary.py b/ciw/auxiliary.py index 299cf3f6..8e16aa78 100644 --- a/ciw/auxiliary.py +++ b/ciw/auxiliary.py @@ -61,7 +61,7 @@ def flatten_list(list_of_lists): def no_routing(ind): """ - Process-based routing fucntion that sends the customer straight + Process-based routing function that sends the customer straight to exit node. It is a placeholder for when NoArrivals is used. """ return [] diff --git a/ciw/deadlock/deadlock_detector.py b/ciw/deadlock/deadlock_detector.py index b0b0c118..7f7130cb 100644 --- a/ciw/deadlock/deadlock_detector.py +++ b/ciw/deadlock/deadlock_detector.py @@ -34,13 +34,13 @@ def action_at_attach_server(self, node, server, individual): def action_at_blockage(self, individual, next_node): """ - The action takn at the 'block_individual' method of the node. + The action taken at the 'block_individual' method of the node. """ pass - def action_at_detatch_server(self, server): + def action_at_detach_server(self, server): """ - The action taken at the 'detatch_server' method of the node. + The action taken at the 'detach_server' method of the node. """ pass @@ -102,7 +102,7 @@ def action_at_attach_server(self, node, server, individual): The action taken at the 'attach_server' method of the node: - If new customer joins server, and they're server is still blocking a customer, then that edge needs to remain. - However it was removed at the action_at_detatch_server, so + However it was removed at the action_at_detach_server, so it needs to be added back in. """ for blq in node.blocked_queue: @@ -122,10 +122,10 @@ def action_at_blockage(self, individual, next_node): for svr in next_node.servers: self.statedigraph.add_edge(str(individual.server), str(svr)) - def action_at_detatch_server(self, server): + def action_at_detach_server(self, server): """ - The action taken at the 'detatch_server' method of the node: - - Remove any edges of servers who have been detatched. + The action taken at the 'detach_server' method of the node: + - Remove any edges of servers who have been detached. """ self.statedigraph.remove_edges_from( list(self.statedigraph.in_edges(str(server))) diff --git a/ciw/dists/distributions.py b/ciw/dists/distributions.py index c6c13e2d..6c706b19 100644 --- a/ciw/dists/distributions.py +++ b/ciw/dists/distributions.py @@ -24,7 +24,7 @@ class Distribution(object): """ - A general distribution from which all other distirbutions will inherit. + A general distribution from which all other distributions will inherit. """ def __repr__(self): return "Distribution" @@ -34,7 +34,7 @@ def sample(self, t=None, ind=None): def _sample(self, t=None, ind=None): """ - Performs vaildity checks before sampling. + Performs validity checks before sampling. """ s = self.sample(t=t, ind=ind) if (isinstance(s, float) or isinstance(s, int)) and s >= 0: @@ -176,7 +176,7 @@ def __init__(self, lower, upper): raise ValueError("Uniform distribution must sample positive numbers only.") if upper < lower: raise ValueError( - "Uniform distirbution upper bound should be >= lower bound." + "Uniform distribution upper bound should be >= lower bound." ) self.lower = lower self.upper = upper @@ -692,9 +692,9 @@ class PhaseType(Distribution): A distribution defined by an initial vector and an absorbing Markov chain Takes: - - `initial_state` the intial probabilities of being in each state - - `absorbing_matrix` the martix representation of the absorbing Markov - chain, with the final state the absorbing state + - `initial_state` the initial probabilities of being in each state. + - `absorbing_matrix` the matrix representation of the absorbing Markov + chain, with the final state the absorbing state. """ def __init__(self, initial_state, absorbing_matrix): @@ -910,7 +910,7 @@ def variance(self): class Coxian(PhaseType): """ - A shortcut for the Coxian distribuion, using the PhaseType distribution + A shortcut for the Coxian distribution, using the PhaseType distribution Takes: - `rates` a vector of rates for each phase @@ -1141,7 +1141,7 @@ def __init__(self, n, prob): ) if not isinstance(n, int) or n <= 0: raise ValueError( - "The number of trials of the Binomial distirbution must be a positive integer." + "The number of trials of the Binomial distribution must be a positive integer." ) self.n = n self.prob = prob diff --git a/ciw/exactnode.py b/ciw/exactnode.py index cd45eb92..0da64b82 100644 --- a/ciw/exactnode.py +++ b/ciw/exactnode.py @@ -11,7 +11,7 @@ class ExactNode(Node): This class inherits from the Node class, and implements a more precise version of addition to - fix discrepencies with floating point numbers. + fix discrepancies with floating point numbers. """ @property @@ -42,7 +42,7 @@ class ExactArrivalNode(ArrivalNode): """Node with exact numerical time precision. Inherits from the ArrivalNode class, implements a - more precise version of addition to fix discrepencies + more precise version of addition to fix discrepancies with floating point numbers. """ @@ -50,18 +50,18 @@ def increment_time(self, original, increment) -> Decimal: """Increment the original time by the increment.""" return Decimal(str(original)) + Decimal(str(increment)) - def inter_arrival(self, nd, clss) -> Decimal: + def inter_arrival(self, node, clss) -> Decimal: """Samples the inter-arrival time for next class and node. Parameters ---------- - nd (Node): Next node. + node (Node): Next node. clss (Individual): Individual class to be selected next. """ return Decimal( str( - self.simulation.inter_arrival_times[nd][clss]._sample( + self.simulation.inter_arrival_times[node][clss]._sample( self.simulation.current_time ) ) diff --git a/ciw/import_params.py b/ciw/import_params.py index d1eda083..2989c211 100644 --- a/ciw/import_params.py +++ b/ciw/import_params.py @@ -95,16 +95,16 @@ def create_network_from_dictionary(params_input): class_change_time_distributions[clss1][clss2] = params['class_change_time_distributions'][clss1][clss2] nodes, classes = [], {} - for nd in range(number_of_nodes): + for node_index in range(number_of_nodes): nodes.append( ServiceCentre( - params['number_of_servers'][nd], - params["queue_capacities"][nd], - class_change_matrices[nd], - preempt_priorities[nd], - params["ps_thresholds"][nd], - params["server_priority_functions"][nd], - params["service_disciplines"][nd], + params['number_of_servers'][node_index], + params["queue_capacities"][node_index], + class_change_matrices[node_index], + preempt_priorities[node_index], + params["ps_thresholds"][node_index], + params["server_priority_functions"][node_index], + params["service_disciplines"][node_index], ) ) for clss_name in params['customer_class_names']: @@ -195,7 +195,7 @@ def validify_dictionary(params): Raises errors if there is something wrong with the parameters dictionary. """ - consistant_num_classes = ( + consistent_num_classes = ( params["number_of_classes"] == len(params["arrival_distributions"]) == len(params["service_distributions"]) @@ -203,9 +203,9 @@ def validify_dictionary(params): == len(params["batching_distributions"]) == len(params["reneging_time_distributions"]) ) - if not consistant_num_classes: - raise ValueError("Ensure consistant number of classes is used throughout.") - consistant_class_names = ( + if not consistent_num_classes: + raise ValueError("Ensure consistent number of classes is used throughout.") + consistent_class_names = ( set(params["arrival_distributions"]) == set(params["service_distributions"]) == set(params["routing"]) @@ -217,8 +217,8 @@ def validify_dictionary(params): == len(params["batching_distributions"]) == len(params["reneging_time_distributions"]) ) - if not consistant_class_names: - raise ValueError("Ensure consistant names for customer classes.") + if not consistent_class_names: + raise ValueError("Ensure consistent names for customer classes.") num_nodes_count = ( [params["number_of_nodes"]] + [len(obs) for obs in params["arrival_distributions"].values()] @@ -230,7 +230,7 @@ def validify_dictionary(params): + [len(params["queue_capacities"])] ) if len(set(num_nodes_count)) != 1: - raise ValueError("Ensure consistant number of nodes is used throughout.") + raise ValueError("Ensure consistent number of nodes is used throughout.") neg_numservers = any( [(isinstance(obs, int) and obs < 0) for obs in params["number_of_servers"]] ) @@ -254,13 +254,13 @@ def validify_dictionary(params): num_nodes = len(params["class_change_matrices"]) == params["number_of_nodes"] if not num_nodes: raise ValueError("Ensure correct nodes used in class_change_matrices.") - for nd in params["class_change_matrices"]: - for row in nd.values(): + for node in params["class_change_matrices"]: + for row in node.values(): if sum(row.values()) > 1.0 or min(row.values()) < 0.0 or max(row.values()) > 1.0: raise ValueError("Ensure that class change matrix is valid.") class_change_names = set([k for matrix in params['class_change_matrices'] for k in matrix.keys()]) if not class_change_names.issubset(set(params['arrival_distributions'])): - raise ValueError("Ensure consistant names for customer classes.") + raise ValueError("Ensure consistent names for customer classes.") if "class_change_time_distributions" in params: class_change_from_names = set(list(params['class_change_time_distributions'].keys())) @@ -273,7 +273,7 @@ def validify_dictionary(params): ) if wrong_class_names: raise ValueError( - "Ensure consistant customer classes used in class_change_time_distributions." + "Ensure consistent customer classes used in class_change_time_distributions." ) if not isinstance(params['system_capacity'], int) and params['system_capacity'] != float('inf'): diff --git a/ciw/network.py b/ciw/network.py index 26205b32..9b7df2ea 100644 --- a/ciw/network.py +++ b/ciw/network.py @@ -88,8 +88,8 @@ def __init__(self, service_centres, customer_classes): set([clss.priority_class for clss in customer_classes.values()]) ) self.priority_class_mapping = {clss: customer_classes[clss].priority_class for clss in customer_classes.keys()} - for nd_id, node in enumerate(self.service_centres): - if all(clss.reneging_time_distributions[nd_id] == None for clss in self.customer_classes.values()): + for node_identifier, node in enumerate(self.service_centres): + if all(clss.reneging_time_distributions[node_identifier] == None for clss in self.customer_classes.values()): node.reneging = False else: node.reneging = True diff --git a/ciw/node.py b/ciw/node.py index 5cd79a94..412e17d6 100644 --- a/ciw/node.py +++ b/ciw/node.py @@ -388,11 +388,11 @@ def decide_preempt(self, individual): ) self.preempt(individual_to_preempt, individual) - def detatch_server(self, server, individual): + def detach_server(self, server, individual): """ Detaches a server from an individual, and vice versa. """ - self.simulation.deadlock_detector.action_at_detatch_server(server) + self.simulation.deadlock_detector.action_at_detach_server(server) server.cust = False server.busy = False individual.server = False @@ -515,16 +515,16 @@ def increment_time(self, original, increment): """ return original + increment - def kill_server(self, srvr): + def kill_server(self, server): """ Kills a server when they go off duty. """ - srvr.total_time = self.increment_time(self.next_event_date, -srvr.start_date) - self.overtime.append(self.increment_time(self.next_event_date, -srvr.shift_end)) - self.all_servers_busy.append(srvr.busy_time) - self.all_servers_total.append(srvr.total_time) - indx = self.servers.index(srvr) - del self.servers[indx] + server.total_time = self.increment_time(self.next_event_date, -server.start_date) + self.overtime.append(self.increment_time(self.next_event_date, -server.shift_end)) + self.all_servers_busy.append(server.busy_time) + self.all_servers_total.append(server.total_time) + index = self.servers.index(server) + del self.servers[index] def next_node(self, ind): """ @@ -558,7 +558,7 @@ def preempt(self, individual_to_preempt, next_individual): individual_to_preempt.time_left = individual_to_preempt.service_end_date - self.now individual_to_preempt.service_time = self.priority_preempt individual_to_preempt.service_end_date = False - self.detatch_server(server, individual_to_preempt) + self.detach_server(server, individual_to_preempt) self.decide_class_change(individual_to_preempt) self.attach_server(server, next_individual) next_individual.service_start_date = self.now @@ -573,7 +573,7 @@ def release(self, next_individual, next_node, reroute=False): - find the individual to release - remove from queue - record relevant information to data record - - detatch individual from server + - detach individual from server - write record - update state tracker - begin service of any waiting customers @@ -590,7 +590,7 @@ def release(self, next_individual, next_node, reroute=False): newly_free_server = None if not isinf(self.c) and not self.slotted: newly_free_server = next_individual.server - self.detatch_server(newly_free_server, next_individual) + self.detach_server(newly_free_server, next_individual) if self.slotted: next_individual.server = False self.reset_individual_attributes(next_individual) diff --git a/ciw/processor_sharing.py b/ciw/processor_sharing.py index df598a71..1e87cccc 100644 --- a/ciw/processor_sharing.py +++ b/ciw/processor_sharing.py @@ -30,8 +30,8 @@ def __init__(self, id_, simulation): def update_all_service_end_dates(self): """ - For each individual reveiving service, calculates the projected end - service dates if the system state remains contant. + For each individual receiving service, calculates the projected end + service dates if the system state remains constant. """ next_occupancy = min(self.number_of_individuals, self.ps_capacity) inds_in_service = [ind for ind in self.all_individuals if ind.with_server] diff --git a/ciw/routing/routing.py b/ciw/routing/routing.py index b9c24a9c..dd6c5c91 100644 --- a/ciw/routing/routing.py +++ b/ciw/routing/routing.py @@ -142,13 +142,13 @@ def find_next_node_from_subset(self, subset, ind): if self.choice == 'jsq': temp_router = JoinShortestQueue(destinations=subset) temp_router.initialise(self.simulation, None) - nd = temp_router.next_node(ind) - return nd.id_number + next_node = temp_router.next_node(ind) + return next_node.id_number if self.choice == 'lb': temp_router = LoadBalancing(destinations=subset) temp_router.initialise(self.simulation, None) - nd = temp_router.next_node(ind) - return nd.id_number + next_node = temp_router.next_node(ind) + return next_node.id_number def update_individual_route(self, ind, next_node_id): """ @@ -228,10 +228,10 @@ def __init__(self, destinations, probs): def error_check_at_initialise(self): if len(self.probs) != len(self.destinations): raise ValueError("Routing probabilities should correspond to destinations, and so should be lists of the same length.") - if not set(self.destinations).issubset(set([nd.id_number for nd in self.simulation.nodes[1:]])): + if not set(self.destinations).issubset(set([node.id_number for node in self.simulation.nodes[1:]])): raise ValueError("Routing destinations should be a subset of the nodes in the network.") - def next_node(self, ind): + def next_node(self, individual): """ Probabilistically chooses the next node from the destinations. """ @@ -289,7 +289,7 @@ def __init__(self, destinations, tie_break='random'): self.tie_break = tie_break def error_check_at_initialise(self): - if not set(self.destinations).issubset(set([nd.id_number for nd in self.simulation.nodes[1:]])): + if not set(self.destinations).issubset(set([node.id_number for node in self.simulation.nodes[1:]])): raise ValueError("Routing destinations should be a subset of the nodes in the network.") def get_queue_size(self, node_index): @@ -345,7 +345,7 @@ def __init__(self, cycle): self.generator = itertools.cycle(self.cycle) def error_check_at_initialise(self): - if not set(self.cycle).issubset(set([nd.id_number for nd in self.simulation.nodes[1:]])): + if not set(self.cycle).issubset(set([node.id_number for node in self.simulation.nodes[1:]])): raise ValueError("Routing destinations should be a subset of the nodes in the network.") def next_node(self, ind): diff --git a/ciw/schedules.py b/ciw/schedules.py index 855948c6..91921c9d 100644 --- a/ciw/schedules.py +++ b/ciw/schedules.py @@ -116,7 +116,7 @@ def __init__(self, slots, slot_sizes, capacitated=False, preemption=False, offse """ if not capacitated: if preemption is not False: - raise ValueError("Pre-emption options not availale for non-capacitated slots.") + raise ValueError("Pre-emption options not available for non-capacitated slots.") if preemption not in [False, 'resume', 'restart', 'resample']: raise ValueError("Pre-emption options should be either 'resume', 'restart', 'resample', or False.") if not isinstance(offset, float): diff --git a/ciw/simulation.py b/ciw/simulation.py index 0786602a..6dd6a4ad 100644 --- a/ciw/simulation.py +++ b/ciw/simulation.py @@ -117,11 +117,11 @@ def show_simulation_to_distributions(self): Adds the simulation object as an attribute of the distribution objects """ for clss in self.network.customer_class_names: - for nd in range(self.network.number_of_nodes): - if self.inter_arrival_times[nd + 1][clss] is not None: - self.inter_arrival_times[nd + 1][clss].simulation = self - self.service_times[nd + 1][clss].simulation = self - self.batch_sizes[nd + 1][clss].simulation = self + for node_index in range(self.network.number_of_nodes): + if self.inter_arrival_times[node_index + 1][clss] is not None: + self.inter_arrival_times[node_index + 1][clss].simulation = self + self.service_times[node_index + 1][clss].simulation = self + self.batch_sizes[node_index + 1][clss].simulation = self def find_and_initialise_routers(self): """ @@ -139,12 +139,12 @@ def find_next_active_node(self): """ mindate = float("Inf") next_active_nodes = [] - for nd in self.active_nodes: - if nd.next_event_date < mindate: - mindate = nd.next_event_date - next_active_nodes = [nd] - elif nd.next_event_date == mindate: - next_active_nodes.append(nd) + for active_node in self.active_nodes: + if active_node.next_event_date < mindate: + mindate = active_node.next_event_date + next_active_nodes = [active_node] + elif active_node.next_event_date == mindate: + next_active_nodes.append(active_node) if len(next_active_nodes) > 1: return random_choice(next_active_nodes) return next_active_nodes[0] @@ -199,7 +199,7 @@ def set_classes( self.NodeTypes = [node_class for _ in range(self.network.number_of_nodes)] else: if len(node_class) != self.network.number_of_nodes: - raise ValueError("Ensure consistant number of nodes is used throughout.") + raise ValueError("Ensure consistent number of nodes is used throughout.") self.NodeTypes = node_class else: self.NodeTypes = [Node for _ in range(self.network.number_of_nodes)] @@ -340,6 +340,6 @@ def wrap_up_servers(self, current_time): the end of the simulation run. Finds the overall server utilisation for each node. """ - for nd in self.transitive_nodes: - nd.wrap_up_servers(current_time) - nd.find_server_utilisation() + for transitive_node in self.transitive_nodes: + transitive_node.wrap_up_servers(current_time) + transitive_node.find_server_utilisation() diff --git a/ciw/trackers/state_tracker.py b/ciw/trackers/state_tracker.py index 5fdc06b9..46fdc7b8 100644 --- a/ciw/trackers/state_tracker.py +++ b/ciw/trackers/state_tracker.py @@ -258,7 +258,7 @@ def __init__(self, groups): Pre-initialises the object with keyword `observed_nodes` """ self.groups = groups - self.observed_nodes = [nd for group in groups for nd in group] + self.observed_nodes = [node for group in groups for node in group] def initialise(self, simulation): """ diff --git a/docs/Guides/Distributions/set_distributions.rst b/docs/Guides/Distributions/set_distributions.rst index 1c9db91c..58197034 100644 --- a/docs/Guides/Distributions/set_distributions.rst +++ b/docs/Guides/Distributions/set_distributions.rst @@ -4,7 +4,7 @@ How to Set Arrival & Service Distributions ========================================== -Ciw offeres a variety of inter-arrival and service time distributions. +Ciw offers a variety of inter-arrival and service time distributions. A full list can be found :ref:`here `. They are objects, that are defined in the :code:`Network` with the :code:`'arrival_distributions'` and :code:`'service_distributions'` keywords. @@ -48,7 +48,7 @@ The system uses the following eight distribution objects: + :code:`ciw.dists.Exponential(rate=6.0)`: + Sample from the `exponential `_ distribution with parameter :math:`\lambda = 6.0`. Expected mean of 0.1666... + :code:`ciw.dists.Uniform(lower=0.1, upper=0.7)`: - + Sample any number between 0.1 and 0.7 with equal probablity. Expected mean of 0.4. + + Sample any number between 0.1 and 0.7 with equal probability. Expected mean of 0.4. + :code:`ciw.dists.Lognormal(mean=-1, sd=0.5)`: + Sample from the `lognormal `_ distribution with parameters :math:`\mu = -1` and :math:`\sigma = 0.5`. Expected mean of 0.4724... + :code:`ciw.dists.Triangular(lower=0.2, mode=0.3, upper=0.7)`: diff --git a/docs/Guides/Distributions/summary_stats.rst b/docs/Guides/Distributions/summary_stats.rst index eb9df9d2..ec53628f 100644 --- a/docs/Guides/Distributions/summary_stats.rst +++ b/docs/Guides/Distributions/summary_stats.rst @@ -4,7 +4,7 @@ How to Access Distributions' Summary Statistics =============================================== -Every distribution object in Ciw has attributes giving summary statisics for the distributions. These are: +Every distribution object in Ciw has attributes giving summary statistics for the distributions. These are: + Mean + Median diff --git a/docs/Guides/Distributions/time_dependent.rst b/docs/Guides/Distributions/time_dependent.rst index 354c8f6e..9475c8a4 100644 --- a/docs/Guides/Distributions/time_dependent.rst +++ b/docs/Guides/Distributions/time_dependent.rst @@ -112,8 +112,7 @@ Here they keyword argument :code:`max_sample_date` is date where no samples will >>> [round(d, 3) for d in Pi.dates] [0.0, 2.274, 2.533, 3.259, 3.303, 3.405, 3.421, 3.477, 3.511, 3.583, 3.784, 6.724, 7.251, 7.282, 7.505, 7.618, 7.756, 7.91] -Here in the interval (0, 3) 2 arrivals were sampled (expected value 3); in the interval (3, 4) 8 arrivals were sampled (expected value 8); in the interval (4, 7) 1 arrival was samples (expected value 3); and in the interval (7, 8) 6 arrivals were sampled (expected value 10); and in the interval (8, 10) 0 arrival was sampled (expeced value 2 -). +Here in the interval (0, 3) 2 arrivals were sampled (expected value 3); in the interval (3, 4) 8 arrivals were sampled (expected value 8); in the interval (4, 7) 1 arrival was samples (expected value 3); and in the interval (7, 8) 6 arrivals were sampled (expected value 10); and in the interval (8, 10) 0 arrival was sampled (expected value 2). The distribution's :code:`sample()` method sampled the scheduled inter-arrival times for these dates:: @@ -198,4 +197,4 @@ And to see it working, a limit of 44 individuals:: >>> Q.simulate_until_max_time(3000) >>> recs = Q.get_all_records() >>> len(recs) - 44 \ No newline at end of file + 44 diff --git a/docs/Guides/Queues/queue_capacities.rst b/docs/Guides/Queues/queue_capacities.rst index 6fb7e531..a9a99fa6 100644 --- a/docs/Guides/Queues/queue_capacities.rst +++ b/docs/Guides/Queues/queue_capacities.rst @@ -7,7 +7,7 @@ How to Set Maximium Queue Capacities A maximum queueing capacity can be set for each node. This means that once the number of people waiting at that node reaches the capacity, then that node cannot receive any more customers until some individuals leave the node. This affects newly arriving customers and customers transitioning from another node differently: + Newly arriving customers who wish to enter the node once capacity is reached are *rejected*. They instead leave the system immediately, and have a data record written that records this rejection (:ref:`see below`). -+ Customers wishing to transition to the node after finishing service at another node are blocked (:ref:`see below`). This means thet remain at their original node, with a server whi is unable to begin another customer's service, until space becomes available. ++ Customers wishing to transition to the node after finishing service at another node are blocked (:ref:`see below`). This means that they remain at their original node, with a server which is unable to begin another customer's service, until space becomes available. In order to implement this, we use the :code:`queue_capacities` keyworks when creating the network:: diff --git a/docs/Guides/Queues/system_capacity.rst b/docs/Guides/Queues/system_capacity.rst index 44fba041..9e6e9acf 100644 --- a/docs/Guides/Queues/system_capacity.rst +++ b/docs/Guides/Queues/system_capacity.rst @@ -1,7 +1,7 @@ .. _system-capacity: =================================================== -How to Set a Maximium Capacity for the Whole System +How to Set a Maximum Capacity for the Whole System =================================================== We have seen that :ref:`node capacities` can define restricted queueing networks. Ciw also allows for a whole system capacity to be set. When a system capacity is set, when the total number of customers present in *all* the nodes of the system is equal to the system capacity, then newly arriving customers will be rejected. Once the total number of customers drops back below the system capacity, then customers will be accepted into the system again. diff --git a/docs/Guides/Routing/routing_objects.rst b/docs/Guides/Routing/routing_objects.rst index 4fbc630c..ade2ac3d 100644 --- a/docs/Guides/Routing/routing_objects.rst +++ b/docs/Guides/Routing/routing_objects.rst @@ -30,7 +30,7 @@ Consider a four node system: + At node 3 customers can either repeat service there with probability 0.25, or leave the system; + At node 4, all customers leave the system. -We can construct a network routing object for this by choosing a set of node routing obejects from the list above. We place them in a list and use the :code:`routers` keyword to create the network object. In this case, the network object would be:: +We can construct a network routing object for this by choosing a set of node routing objects from the list above. We place them in a list and use the :code:`routers` keyword to create the network object. In this case, the network object would be:: >>> import ciw >>> R = ciw.routing.NetworkRouting( @@ -55,7 +55,7 @@ This network object can then be used to create a network:: Notes ~~~~~ -+ Note that a the :code:`routing` keywork when creating a network object requires a network routing object, *not* a node routing object. This is true even when there is only one node in the network. ++ Note that the :code:`routing` parameter of :code:`ciw.create_network` requires a network routing object, *not* a node routing object. This is true even when there is only one node in the network. + Note also that, similar to the use of most other keywords when creating a network object, that routing can be customer class dependent. For example, a one node network with two customer classes, both classes having different routing:: diff --git a/docs/Guides/Services/preemption.rst b/docs/Guides/Services/preemption.rst index 670dc07e..0ac094d9 100644 --- a/docs/Guides/Services/preemption.rst +++ b/docs/Guides/Services/preemption.rst @@ -49,7 +49,7 @@ In order to implement pre-emptive or non-pre-emptive schedules, the :code:`ciw.S number_of_servers=[ ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption=False), # non-preemptive ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="resample"), # preemptive and resamples service time - ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="restart"), # preemptive and restarts origional service time + ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="restart"), # preemptive and restarts original service time ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="resume"), # preemptive and continues services where left off ciw.Schedule(numbers_of_servers=[2, 0, 1], shift_end_dates=[10, 30, 100], preemption="reroute") # preemptive and sends the individual to another node ] diff --git a/docs/Guides/Services/processor-sharing.rst b/docs/Guides/Services/processor-sharing.rst index 04389d63..3c6d8229 100644 --- a/docs/Guides/Services/processor-sharing.rst +++ b/docs/Guides/Services/processor-sharing.rst @@ -88,7 +88,7 @@ Capacitated Process Sharing --------------------------- A *capacitated processor sharing queue*, or an R-PS queue ([XL09]_), is another generalisation of a processor sharing queue. -It has parameter :math:`R`, a threshold where if the number of customers exceeds it, service switches to processor sharing shared amongs :math:`R` processors. That is when there are :math:`R` or less customers, each customer is served independently with rate 1; when there are :math:`n > R` customers, each customer is served with rate :math:`R/n`. +It has parameter :math:`R`, a threshold where if the number of customers exceeds it, service switches to processor sharing shared among :math:`R` processors. That is when there are :math:`R` or less customers, each customer is served independently with rate 1; when there are :math:`n > R` customers, each customer is served with rate :math:`R/n`. With capacitated processor sharing queues, we can set the threshold :math:`R` by setting a :code:`ps_threshold` in the network object. diff --git a/docs/Guides/Simulation/results.rst b/docs/Guides/Simulation/results.rst index 70b2a664..c1447223 100644 --- a/docs/Guides/Simulation/results.rst +++ b/docs/Guides/Simulation/results.rst @@ -47,7 +47,7 @@ And so relevant data can be gathered using list comprehension:: >>> sum(waiting_times) / len(waiting_times) 0.3989747... -For easier manipulation, use in conjuction with `Pandas `_ is recommended, allowing for easier filtering, grouping, and summary statistics calculations. Lists of data records convert to Pandas data frames smoothly: +For easier manipulation, use in conjunction with `Pandas `_ is recommended, allowing for easier filtering, grouping, and summary statistics calculations. Lists of data records convert to Pandas data frames smoothly: >>> import pandas as pd >>> recs_pd = pd.DataFrame(recs) diff --git a/docs/Guides/Simulation/seed.rst b/docs/Guides/Simulation/seed.rst index 58b8d703..4e19bc4a 100644 --- a/docs/Guides/Simulation/seed.rst +++ b/docs/Guides/Simulation/seed.rst @@ -5,7 +5,7 @@ How to Set a Seed ================= To ensure reproducibility of results users can set a seed for all the random number streams that Ciw uses. -This can be done using the Ciw functon :code:`ciw.seed`:: +This can be done using the Ciw function :code:`ciw.seed`:: >>> import ciw >>> ciw.seed(5) diff --git a/docs/Guides/Simulation/sim_maxtime.rst b/docs/Guides/Simulation/sim_maxtime.rst index 99e7ba78..d6b755f1 100644 --- a/docs/Guides/Simulation/sim_maxtime.rst +++ b/docs/Guides/Simulation/sim_maxtime.rst @@ -30,6 +30,6 @@ We will see there there have been three arrivals at dates 7, 14 and 21, but only [7.0, 14.0] >>> Q.current_time 22.0 - >>> [nd.next_event_date for nd in Q.nodes] + >>> [node.next_event_date for node in Q.nodes] [28.0, 23.0, inf] diff --git a/doctests.py b/doctests.py index 3b53eb42..2222ffa9 100644 --- a/doctests.py +++ b/doctests.py @@ -4,10 +4,11 @@ import os import unittest import sys -from typing import Any -def load_tests(loader: unittest.TestLoader, tests: unittest.TestSuite, ignorex: Any) -> unittest.TestSuite: +def load_tests( + loader: unittest.TestLoader, tests: unittest.TestSuite, ignorex: object +) -> unittest.TestSuite: """ Discover and add all reStructuredText (.rst) doctest files within the current directory tree to the test suite. @@ -17,7 +18,7 @@ def load_tests(loader: unittest.TestLoader, tests: unittest.TestSuite, ignorex: The test loader instance used to load the tests. tests : unittest.TestSuite The existing test suite to which doctest suites will be added. - ignorex : Any + ignorex : object A placeholder parameter (typically unused) required by the unittest framework. Returns @@ -45,8 +46,7 @@ def load_tests(loader: unittest.TestLoader, tests: unittest.TestSuite, ignorex: if f.endswith(".rst"): tests.addTests( doctest.DocFileSuite( - os.path.join(root, f), - optionflags=doctest.ELLIPSIS + os.path.join(root, f), optionflags=doctest.ELLIPSIS ) ) return tests @@ -55,4 +55,3 @@ def load_tests(loader: unittest.TestLoader, tests: unittest.TestSuite, ignorex: if __name__ == "__main__": if sys.version_info >= (3, 6): unittest.main() - diff --git a/tests/test_arrival_node.py b/tests/test_arrival_node.py index 59ffdebc..fc8dbd8a 100644 --- a/tests/test_arrival_node.py +++ b/tests/test_arrival_node.py @@ -415,14 +415,14 @@ def test_batching_custom(self): Q = ciw.Simulation(N) N = Q.transitive_nodes[0] - observerd_inds = [] + observed_individuals = [] for _ in range(20): - observerd_inds.append(len(N.all_individuals)) + observed_individuals.append(len(N.all_individuals)) Q.nodes[0].have_event() # Numbers of individuals should only increase by 1 or by 5 self.assertEqual( - observerd_inds, + observed_individuals, [0, 1, 6, 11, 12, 13, 14, 15, 20, 25, 30, 35, 40, 41, 42, 43, 48, 49, 54, 55], ) diff --git a/tests/test_node.py b/tests/test_node.py index 4b54cbde..46fac3f5 100644 --- a/tests/test_node.py +++ b/tests/test_node.py @@ -500,7 +500,7 @@ def test_release_blocked_individual_method(self): N1.blocked_queue = [(1, 1), (2, 100)] N1.len_blocked_queue = 2 rel_ind = N1.individuals[0].pop(0) - N1.detatch_server(rel_ind.server, rel_ind) + N1.detach_server(rel_ind.server, rel_ind) Q.current_time = 110 N1.release_blocked_individual() @@ -1033,7 +1033,7 @@ def test_records_correct_server_id(self): def custom_server_priority(srv, ind): """ - A custom server priority function that priortises server 1 for + A custom server priority function that prioritises server 1 for customer class 0 and server 2 for customer class 1. """ if ind.customer_class == 'Class 0': diff --git a/tests/test_sampling.py b/tests/test_sampling.py index f3dea446..70f4f0d4 100644 --- a/tests/test_sampling.py +++ b/tests/test_sampling.py @@ -201,7 +201,7 @@ def test_sampling_uniform_dist_hypothesis(self, u, rm): ) Q = ciw.Simulation(N) Nu = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue( ul <= Nu.simulation.service_times[Nu.id_number]['Customer']._sample() <= uh ) @@ -264,7 +264,7 @@ def test_sampling_deterministic_dist_hypothesis(self, d, rm): ) Q = ciw.Simulation(N) Nd = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertEqual(Nd.simulation.service_times[Nd.id_number]['Customer']._sample(), d) self.assertEqual( Nd.simulation.inter_arrival_times[Nd.id_number]['Customer']._sample(), d @@ -326,7 +326,7 @@ def test_sampling_triangular_dist_hypothesis(self, t, rm): ) Q = ciw.Simulation(N) Nt = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue(tl <= Nt.simulation.service_times[Nt.id_number]['Customer']._sample() <= th) self.assertTrue(tl <= Nt.simulation.inter_arrival_times[Nt.id_number]['Customer']._sample() <= th) @@ -396,7 +396,7 @@ def test_sampling_exponential_dist_hypothesis(self, e, rm): ) Q = ciw.Simulation(N) Ne = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue( Ne.simulation.service_times[Ne.id_number]['Customer']._sample() >= 0.0 ) @@ -461,7 +461,7 @@ def test_sampling_gamma_dist_hypothesis(self, ga, gb, rm): ) Q = ciw.Simulation(N) Ng = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue( Ng.simulation.service_times[Ng.id_number]['Customer']._sample() >= 0.0 ) @@ -522,7 +522,7 @@ def test_sampling_lognormal_dist_hypothesis(self, lm, lsd, rm): ) Q = ciw.Simulation(N) Nl = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue(Nl.simulation.service_times[Nl.id_number]['Customer']._sample() >= 0.0) self.assertTrue(Nl.simulation.inter_arrival_times[Nl.id_number]['Customer']._sample() >= 0.0) @@ -584,7 +584,7 @@ def test_sampling_weibull_dist_hypothesis(self, wa, wb, rm): ) Q = ciw.Simulation(N) Nw = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue( Nw.simulation.service_times[Nw.id_number]['Customer']._sample() >= 0.0 ) @@ -650,7 +650,7 @@ def test_sampling_normal_dist_hypothesis(self, nm, ns, rm): ) Q = ciw.Simulation(N) Nw = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue(Nw.simulation.service_times[Nw.id_number]['Customer']._sample() >= 0.0) self.assertTrue(Nw.simulation.inter_arrival_times[Nw.id_number]['Customer']._sample() >= 0.0) @@ -719,7 +719,7 @@ def test_sampling_empirical_dist_hypothesis(self, dist, rm): ) Q = ciw.Simulation(N) Nem = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue( Nem.simulation.service_times[Nem.id_number]['Customer']._sample() in set([7.0, 7.1, 7.2, 7.3, 7.7, 7.8]) @@ -806,7 +806,7 @@ def test_sampling_pmf_dist_hypothesis(self, custs, rm): ) Q = ciw.Simulation(N) Nc = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue(Nc.simulation.service_times[Nc.id_number]['Customer']._sample() in set(cust_vals)) self.assertTrue(Nc.simulation.inter_arrival_times[Nc.id_number]['Customer']._sample() in set(cust_vals)) @@ -1265,28 +1265,28 @@ def test_mixture_distributions(self): D5 = ciw.dists.Deterministic(5.0) D8 = ciw.dists.Deterministic(8.0) - Mixted_100 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[1, 0, 0]) - m100_samples = [Mixted_100.sample() for _ in range(10)] + mixture_distribution_100 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[1, 0, 0]) + m100_samples = [mixture_distribution_100.sample() for _ in range(10)] m100_expected = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - self.assertEqual(str(Mixted_100), 'MixtureDistribution') + self.assertEqual(str(mixture_distribution_100), 'MixtureDistribution') self.assertEqual(m100_samples, m100_expected) - Mixted_010 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[0, 1, 0]) - m010_samples = [Mixted_010.sample() for _ in range(10)] + mixture_distribution_010 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[0, 1, 0]) + m010_samples = [mixture_distribution_010.sample() for _ in range(10)] m010_expected = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5] - self.assertEqual(str(Mixted_010), 'MixtureDistribution') + self.assertEqual(str(mixture_distribution_010), 'MixtureDistribution') self.assertEqual(m010_samples, m010_expected) - Mixted_001 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[0, 0, 1]) - m001_samples = [Mixted_001.sample() for _ in range(10)] + mixture_distribution_001 = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[0, 0, 1]) + m001_samples = [mixture_distribution_001.sample() for _ in range(10)] m001_expected = [8, 8, 8, 8, 8, 8, 8, 8, 8, 8] - self.assertEqual(str(Mixted_001), 'MixtureDistribution') + self.assertEqual(str(mixture_distribution_001), 'MixtureDistribution') self.assertEqual(m001_samples, m001_expected) - Mixted_eq = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[1/3, 1/3, 1/3]) - meq_samples = [Mixted_eq.sample() for _ in range(10)] + mixture_distribution = ciw.dists.MixtureDistribution(dists=[D1, D5, D8], probs=[1/3, 1/3, 1/3]) + meq_samples = [mixture_distribution.sample() for _ in range(10)] meq_expected = [5, 8, 1, 8, 5, 1, 8, 5, 8, 8] - self.assertEqual(str(Mixted_eq), 'MixtureDistribution') + self.assertEqual(str(mixture_distribution), 'MixtureDistribution') self.assertEqual(meq_samples, meq_expected) def test_mixture_summary_stats(self): @@ -1496,7 +1496,7 @@ def test_sampling_erlang_dist_hypothesis(self, sizes, rates, rm): ) Q = ciw.Simulation(N) Nw = Q.transitive_nodes[0] - for itr in range(10): # Because repition happens in the simulation + for itr in range(10): # Because repetition happens in the simulation self.assertTrue(Nw.simulation.service_times[Nw.id_number]['Customer']._sample() >= 0.0) self.assertTrue(Nw.simulation.inter_arrival_times[Nw.id_number]['Customer']._sample() >= 0.0) diff --git a/tests/test_scheduling.py b/tests/test_scheduling.py index 5ea9ae83..70d2a04e 100644 --- a/tests/test_scheduling.py +++ b/tests/test_scheduling.py @@ -125,7 +125,7 @@ def test_kill_server_method(self): N.servers[0].offduty = True self.assertEqual([obs.busy for obs in N.servers], [True, False]) self.assertEqual([obs.offduty for obs in N.servers], [True, False]) - N.detatch_server(N.servers[0], ind) + N.detach_server(N.servers[0], ind) self.assertEqual([str(obs) for obs in N.servers], ["Server 3 at Node 1"]) def test_add_new_servers_method(self): diff --git a/tests/test_simulation.py b/tests/test_simulation.py index c6702476..fd89f5f8 100644 --- a/tests/test_simulation.py +++ b/tests/test_simulation.py @@ -240,7 +240,7 @@ def test_simulate_until_max_customers(self): Q3 = ciw.Simulation(N) Q3.simulate_until_max_customers(10, method="Arrive") self.assertEqual(Q3.nodes[0].number_of_individuals, 10) - all_inds = sum([len(nd.all_individuals) for nd in Q3.nodes[1:]]) + all_inds = sum([len(nodes.all_individuals) for nodes in Q3.nodes[1:]]) rejected_records = Q3.get_all_records(only=["rejection"]) number_of_losses = len(rejected_records) self.assertEqual(all_inds, 10) @@ -1575,19 +1575,19 @@ def next_node_for_rerouting(self, ind): Q.simulate_until_max_time(2.7) recs = Q.get_all_records() - nd_1 = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_1], [0.7, 1.0, 1.4, 2.0, 2.1]) - self.assertEqual([round(r.service_time, 5) for r in nd_1], [0.2, 0.2, 0.2, 0.2, 0.2]) - self.assertEqual([round(r.exit_date, 5) for r in nd_1], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([r.destination for r in nd_1], [-1, -1, -1, 2, -1]) - self.assertEqual([r.record_type for r in nd_1], ['service', 'service', 'service', 'interrupted service', 'service']) + node_1_records = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_1_records], [0.7, 1.0, 1.4, 2.0, 2.1]) + self.assertEqual([round(r.service_time, 5) for r in node_1_records], [0.2, 0.2, 0.2, 0.2, 0.2]) + self.assertEqual([round(r.exit_date, 5) for r in node_1_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([r.destination for r in node_1_records], [-1, -1, -1, 2, -1]) + self.assertEqual([r.record_type for r in node_1_records], ['service', 'service', 'service', 'interrupted service', 'service']) - nd_2 = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_2], [2.1]) - self.assertEqual([round(r.service_time, 5) for r in nd_2], [0.5]) - self.assertEqual([round(r.exit_date, 5) for r in nd_2], [2.6]) - self.assertEqual([r.destination for r in nd_2], [-1]) - self.assertEqual([r.record_type for r in nd_2], ['service']) + node_2_records = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_2_records], [2.1]) + self.assertEqual([round(r.service_time, 5) for r in node_2_records], [0.5]) + self.assertEqual([round(r.exit_date, 5) for r in node_2_records], [2.6]) + self.assertEqual([r.destination for r in node_2_records], [-1]) + self.assertEqual([r.record_type for r in node_2_records], ['service']) """ Class 0 arrive to Node 1 every 0.7, service lasts 0.2 @@ -1631,19 +1631,19 @@ def next_node_for_rerouting(self, ind): Q.simulate_until_max_time(2.7) recs = Q.get_all_records() - nd_1 = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_1], [0.7, 1.0, 1.4, 2.0, 2.1]) - self.assertEqual([round(r.service_time, 5) for r in nd_1], [0.2, 0.2, 0.2, 0.2, 0.2]) - self.assertEqual([round(r.exit_date, 5) for r in nd_1], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([r.destination for r in nd_1], [2, 2, 2, 2, 2]) - self.assertEqual([r.record_type for r in nd_1], ['service', 'service', 'service', 'interrupted service', 'service']) + node_1_records = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_1_records], [0.7, 1.0, 1.4, 2.0, 2.1]) + self.assertEqual([round(r.service_time, 5) for r in node_1_records], [0.2, 0.2, 0.2, 0.2, 0.2]) + self.assertEqual([round(r.exit_date, 5) for r in node_1_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([r.destination for r in node_1_records], [2, 2, 2, 2, 2]) + self.assertEqual([r.record_type for r in node_1_records], ['service', 'service', 'service', 'interrupted service', 'service']) - nd_2 = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_2], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([round(r.service_time, 5) for r in nd_2], [0.1, 0.1, 0.1, 0.1, 0.1]) - self.assertEqual([round(r.exit_date, 5) for r in nd_2], [1.0, 1.3, 1.7, 2.2, 2.4]) - self.assertEqual([r.destination for r in nd_2], [-1, -1, -1, -1, -1]) - self.assertEqual([r.record_type for r in nd_2], ['service', 'service', 'service', 'service', 'service']) + node_2_records = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_2_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([round(r.service_time, 5) for r in node_2_records], [0.1, 0.1, 0.1, 0.1, 0.1]) + self.assertEqual([round(r.exit_date, 5) for r in node_2_records], [1.0, 1.3, 1.7, 2.2, 2.4]) + self.assertEqual([r.destination for r in node_2_records], [-1, -1, -1, -1, -1]) + self.assertEqual([r.record_type for r in node_2_records], ['service', 'service', 'service', 'service', 'service']) def test_reroute_preemption_classpriorities_process_based(self): """ @@ -1691,19 +1691,19 @@ def from_1_to_2(ind, simulation): Q.simulate_until_max_time(2.7) recs = Q.get_all_records() - nd_1 = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_1], [0.7, 1.0, 1.4, 2.0, 2.1]) - self.assertEqual([round(r.service_time, 5) for r in nd_1], [0.2, 0.2, 0.2, 0.2, 0.2]) - self.assertEqual([round(r.exit_date, 5) for r in nd_1], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([r.destination for r in nd_1], [2, 2, 2, 2, 2]) - self.assertEqual([r.record_type for r in nd_1], ['service', 'service', 'service', 'interrupted service', 'service']) + node_1_records = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_1_records], [0.7, 1.0, 1.4, 2.0, 2.1]) + self.assertEqual([round(r.service_time, 5) for r in node_1_records], [0.2, 0.2, 0.2, 0.2, 0.2]) + self.assertEqual([round(r.exit_date, 5) for r in node_1_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([r.destination for r in node_1_records], [2, 2, 2, 2, 2]) + self.assertEqual([r.record_type for r in node_1_records], ['service', 'service', 'service', 'interrupted service', 'service']) - nd_2 = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_2], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([round(r.service_time, 5) for r in nd_2], [0.1, 0.1, 0.1, 0.1, 0.1]) - self.assertEqual([round(r.exit_date, 5) for r in nd_2], [1.0, 1.3, 1.7, 2.2, 2.4]) - self.assertEqual([r.destination for r in nd_2], [-1, -1, -1, -1, -1]) - self.assertEqual([r.record_type for r in nd_2], ['service', 'service', 'service', 'service', 'service']) + node_2_records = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_2_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([round(r.service_time, 5) for r in node_2_records], [0.1, 0.1, 0.1, 0.1, 0.1]) + self.assertEqual([round(r.exit_date, 5) for r in node_2_records], [1.0, 1.3, 1.7, 2.2, 2.4]) + self.assertEqual([r.destination for r in node_2_records], [-1, -1, -1, -1, -1]) + self.assertEqual([r.record_type for r in node_2_records], ['service', 'service', 'service', 'service', 'service']) def test_rerouting_ignores_queue_capacities(self): """ @@ -1766,19 +1766,19 @@ def next_node_for_rerouting(self, ind): Q.simulate_until_max_time(3.3) recs = Q.get_all_records() - nd_1 = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date)[:5] - self.assertEqual([round(r.arrival_date, 5) for r in nd_1], [0.7, 1.0, 1.4, 2.0, 2.1]) - self.assertEqual([round(r.service_time, 5) for r in nd_1], [0.2, 0.2, 0.2, 0.2, 0.2]) - self.assertEqual([round(r.exit_date, 5) for r in nd_1], [0.9, 1.2, 1.6, 2.1, 2.3]) - self.assertEqual([r.destination for r in nd_1], [-1, -1, -1, 2, -1]) - self.assertEqual([r.record_type for r in nd_1], ['service', 'service', 'service', 'interrupted service', 'service']) + node_1_records = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date)[:5] + self.assertEqual([round(r.arrival_date, 5) for r in node_1_records], [0.7, 1.0, 1.4, 2.0, 2.1]) + self.assertEqual([round(r.service_time, 5) for r in node_1_records], [0.2, 0.2, 0.2, 0.2, 0.2]) + self.assertEqual([round(r.exit_date, 5) for r in node_1_records], [0.9, 1.2, 1.6, 2.1, 2.3]) + self.assertEqual([r.destination for r in node_1_records], [-1, -1, -1, 2, -1]) + self.assertEqual([r.record_type for r in node_1_records], ['service', 'service', 'service', 'interrupted service', 'service']) - nd_2 = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date)[:5] - self.assertEqual([round(r.arrival_date, 5) for r in nd_2], [0.6, 1.2, 1.8, 2.1, 2.4]) - self.assertEqual([str(round(r.service_time, 5)) for r in nd_2], ['0.7', 'nan', '0.7', '0.7', 'nan']) - self.assertEqual([round(r.exit_date, 5) for r in nd_2], [1.3, 1.2, 2.5, 3.2, 2.4]) - self.assertEqual([str(r.destination) for r in nd_2], ['-1', 'nan', '-1', '-1', 'nan']) - self.assertEqual([r.record_type for r in nd_2], ['service', 'rejection', 'service', 'service', 'rejection']) + node_2_records = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date)[:5] + self.assertEqual([round(r.arrival_date, 5) for r in node_2_records], [0.6, 1.2, 1.8, 2.1, 2.4]) + self.assertEqual([str(round(r.service_time, 5)) for r in node_2_records], ['0.7', 'nan', '0.7', '0.7', 'nan']) + self.assertEqual([round(r.exit_date, 5) for r in node_2_records], [1.3, 1.2, 2.5, 3.2, 2.4]) + self.assertEqual([str(r.destination) for r in node_2_records], ['-1', 'nan', '-1', '-1', 'nan']) + self.assertEqual([r.record_type for r in node_2_records], ['service', 'rejection', 'service', 'service', 'rejection']) def test_reroute_at_shift_change(self): """ @@ -1823,19 +1823,19 @@ def next_node_for_rerouting(self, ind): Q.simulate_until_max_time(7.5) recs = Q.get_all_records() - nd_1 = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_1], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) - self.assertEqual([round(r.service_time, 5) for r in nd_1], [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]) - self.assertEqual([round(r.exit_date, 5) for r in nd_1], [1.4, 2.4, 3.4, 4.2, 6.5, 6.9, 7.4]) - self.assertEqual([r.destination for r in nd_1], [-1, -1, -1, 2, -1, -1, -1]) - self.assertEqual([r.record_type for r in nd_1], ['service', 'service', 'service', 'interrupted service', 'service', 'service', 'service']) - - nd_2 = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) - self.assertEqual([round(r.arrival_date, 5) for r in nd_2], [4.2]) - self.assertEqual([round(r.service_time, 5) for r in nd_2], [1.0]) - self.assertEqual([round(r.exit_date, 5) for r in nd_2], [5.2]) - self.assertEqual([r.destination for r in nd_2], [-1]) - self.assertEqual([r.record_type for r in nd_2], ['service']) + node_1_records = sorted([r for r in recs if r.node == 1], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_1_records], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) + self.assertEqual([round(r.service_time, 5) for r in node_1_records], [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]) + self.assertEqual([round(r.exit_date, 5) for r in node_1_records], [1.4, 2.4, 3.4, 4.2, 6.5, 6.9, 7.4]) + self.assertEqual([r.destination for r in node_1_records], [-1, -1, -1, 2, -1, -1, -1]) + self.assertEqual([r.record_type for r in node_1_records], ['service', 'service', 'service', 'interrupted service', 'service', 'service', 'service']) + + node_2_records = sorted([r for r in recs if r.node == 2], key=lambda r: r.arrival_date) + self.assertEqual([round(r.arrival_date, 5) for r in node_2_records], [4.2]) + self.assertEqual([round(r.service_time, 5) for r in node_2_records], [1.0]) + self.assertEqual([round(r.exit_date, 5) for r in node_2_records], [5.2]) + self.assertEqual([r.destination for r in node_2_records], [-1]) + self.assertEqual([r.record_type for r in node_2_records], ['service']) class TestServiceDisciplines(unittest.TestCase): diff --git a/tests/test_state_tracker.py b/tests/test_state_tracker.py index e904c018..6de61787 100644 --- a/tests/test_state_tracker.py +++ b/tests/test_state_tracker.py @@ -1479,11 +1479,11 @@ def test_prob_track_history_two_node_two_class(self): def test_compare_state_probabilities_to_analytical(self): # Example: λ = 1, μ = 3 - lamda = 1 + rate_lambda = 1 mu = 3 ciw.seed(0) N = ciw.create_network( - arrival_distributions=[ciw.dists.Exponential(lamda)], + arrival_distributions=[ciw.dists.Exponential(rate_lambda)], service_distributions=[ciw.dists.Exponential(mu)], number_of_servers=[1], ) @@ -1493,7 +1493,7 @@ def test_compare_state_probabilities_to_analytical(self): observation_period=(500, 20000) ) - vec = [(lamda / mu) ** i for i in sorted(state_probs.keys())] + vec = [(rate_lambda / mu) ** i for i in sorted(state_probs.keys())] expected_probs = [v / sum(vec) for v in vec] for state in state_probs: @@ -1511,11 +1511,11 @@ def test_compare_state_probabilities_to_analytical(self): self.assertEqual(round(error_squared, 4), 0) # Example: λ = 1, μ = 4 - lamda = 1 + rate_lambda = 1 mu = 4 ciw.seed(0) N = ciw.create_network( - arrival_distributions=[ciw.dists.Exponential(lamda)], + arrival_distributions=[ciw.dists.Exponential(rate_lambda)], service_distributions=[ciw.dists.Exponential(mu)], number_of_servers=[1], ) @@ -1525,7 +1525,7 @@ def test_compare_state_probabilities_to_analytical(self): observation_period=(500, 20000) ) - vec = [(lamda / mu) ** i for i in sorted(state_probs.keys())] + vec = [(rate_lambda / mu) ** i for i in sorted(state_probs.keys())] expected_probs = [v / sum(vec) for v in vec] for state in state_probs: @@ -1543,11 +1543,11 @@ def test_compare_state_probabilities_to_analytical(self): self.assertEqual(round(error_squared, 4), 0) # Example: λ = 1, μ = 5 - lamda = 1 + rate_lambda = 1 mu = 5 ciw.seed(0) N = ciw.create_network( - arrival_distributions=[ciw.dists.Exponential(lamda)], + arrival_distributions=[ciw.dists.Exponential(rate_lambda)], service_distributions=[ciw.dists.Exponential(mu)], number_of_servers=[1], ) @@ -1557,7 +1557,7 @@ def test_compare_state_probabilities_to_analytical(self): observation_period=(500, 20000) ) - vec = [(lamda / mu) ** i for i in sorted(state_probs.keys())] + vec = [(rate_lambda / mu) ** i for i in sorted(state_probs.keys())] expected_probs = [v / sum(vec) for v in vec] for state in state_probs: