def _satisfy_ub_reqs(layout: Layout, avail_out_places): height = layout.data.shape[0] required_idxs = [[] for _ in range(layout.width)] required_values = [[] for _ in range(layout.width)] for i in range(height): if pd.isnull(avail_out_places[i]): continue col_idxs = [] col_values = [] used_sum = 0 for j in range(layout.width): amount = layout.data[get_layout_col(j)][i] required = layout.data[get_required_col(j)][i] if not required and not pd.isnull(amount): col_idxs.append(j) col_values.append(int(amount)) used_sum += int(amount) if used_sum <= avail_out_places[i]: continue coef = avail_out_places[i] / used_sum for idx, old_value in zip(col_idxs, col_values): required_values[idx].append(int(old_value * coef)) required_idxs[idx].append(i) for i in range(layout.width): layout.data[get_layout_col(i)][required_idxs[i]] = np.array( required_values[i])
def _fill_layout_with_result(layout, result): data = layout.data height = data[layout_config.IN_PLACES_COL].shape[0] cur_var_idx = 0 col_idxs = {} values = {} for i in range(height): column_idx = i % layout.width if data[layout_config.IN_PLACES_COL][i] is None: continue cur_idx = get_layout_col(column_idx) cur_req_idx = get_required_col(column_idx) res_places = 0 max_places = data[layout_config.IN_PLACES_COL][i] for j in range(i, min(i + param_config.MAX_DAYS + 1, height)): delta = (data[layout_config.OUT_DATES_COL][j] - data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if data[cur_req_idx][j]: continue if column_idx not in col_idxs: col_idxs[column_idx] = [] values[column_idx] = [] col_idxs[column_idx].append(j) values[column_idx].append(result[cur_var_idx]) #data[cur_idx][j] = result[cur_var_idx] res_places += result[cur_var_idx] cur_var_idx += 1 data[cur_idx][i] = res_places if res_places > max_places else max_places for column_idx in col_idxs: col_vals = np.array(values[column_idx]) data[get_layout_col(column_idx)][col_idxs[column_idx]] = col_vals
def _update_required_fields_with_col_priorities( new_layout_obj: core_layout.Layout, old_layout_obj: core_layout.Layout, avail_in_places, avail_out_places, old_avail_in_places, old_avail_out_places): required_idxs = [[] for _ in range(old_layout_obj.width)] required_values = [[] for _ in range(old_layout_obj.width)] for i in range(old_layout_obj.data.shape[0]): if avail_in_places[i] is None or old_avail_in_places[ i] is None or old_avail_in_places == 0: continue coef = avail_in_places[i] / old_avail_in_places[i] current_idx = i % old_layout_obj.width for j in range( i, min(i + old_layout_obj.max_days + 1, old_layout_obj.data.shape[0])): delta = (old_layout_obj.data[OUT_DATES_COL][j] - old_layout_obj.data[IN_DATES_COL][i]).days if np.isnan(delta) or delta < old_layout_obj.min_days: continue if delta > old_layout_obj.max_days: break if avail_out_places[j] is None or old_avail_out_places[j] is None: continue amount = old_layout_obj.data[get_layout_col(current_idx)][j] required = old_layout_obj.data[get_required_col(current_idx)][j] if required: new_amount = int(amount * coef) required_values[current_idx].append(new_amount) required_idxs[current_idx].append(j) for i in range(old_layout_obj.width): new_layout_obj.data[get_required_col(i)][required_idxs[i]] = True new_layout_obj.data[get_layout_col(i)][required_idxs[i]] = np.array( required_values[i])
def _update_required_fields_with_row_priorities( new_layout_obj: core_layout.Layout, old_layout_obj: core_layout.Layout, avail_out_places, old_avail_out_places): required_idxs = [[] for _ in range(old_layout_obj.width)] required_values = [[] for _ in range(old_layout_obj.width)] for i in range(old_layout_obj.data.shape[0]): if avail_out_places[i] is None or old_avail_out_places[i] == 0: continue col_idxs = [] col_values = [] new_col_values = [] used_sum = 0 for j in range(new_layout_obj.width): old_amount = old_layout_obj.data[get_layout_col(j)][i] new_amount = new_layout_obj.data[get_layout_col(j)][i] required = old_layout_obj.data[get_required_col(j)][i] if required: col_idxs.append(j) col_values.append(int(old_amount)) new_col_values.append(int(new_amount)) used_sum += int(new_amount) if used_sum <= avail_out_places[i]: continue coef = avail_out_places[i] / old_avail_out_places[i] for idx, old_value, new_value in zip(col_idxs, col_values, new_col_values): required_values[idx].append(min(int(old_value * coef), new_value)) required_idxs[idx].append(i) for i in range(old_layout_obj.width): new_layout_obj.data[get_layout_col(i)][required_idxs[i]] = np.array( required_values[i])
def _set_initial_values(layout: Layout, avail_in_places, corr_relations, vars_num): height = layout.data[layout_config.IN_PLACES_COL].shape[0] init_values = [[] for _ in range(layout.width)] init_idxs = [[] for _ in range(layout.width)] for i in range(height): cur_idx = i % layout.width cur_init_values = [ int(pr * avail_in_places[i]) if avail_in_places[i] is not None else None for pr in corr_relations[i] ] for j in range(i, min(i + layout.max_days + 1, height)): delta = (layout.data[layout_config.OUT_DATES_COL][j] - layout.data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break cur_init_idx = delta - layout.min_days if not layout.data[get_required_col(cur_idx)][j]: init_idxs[cur_idx].append(j) init_values[cur_idx].append(cur_init_values[cur_init_idx]) for i in range(layout.width): layout.data[get_layout_col(i)][init_idxs[i]] = np.array(init_values[i]) return vars_num
def _get_avail_in_places(layout): out_of_order = layout.out_of_order layout_data = layout.data height = layout_data.shape[0] width = layout.width out_of_order_places = [0] * height for i, data_list in enumerate(out_of_order): for _, amount, _ in data_list: out_of_order_places[i] += amount in_places = [] for i in range(height): cur_sum = 0 cur_idx = i % width for j in range(i, min(i + layout.max_days + 1, height)): delta = (layout_data[layout_config.OUT_DATES_COL][j] - layout_data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if layout_data[get_required_col(cur_idx)][j]: cur_sum += layout_data[get_layout_col(cur_idx)][j] cur_sum += out_of_order_places[i] in_max_places = layout_data[layout_config.IN_PLACES_COL][i] if in_max_places is not None and cur_sum > in_max_places: raise ErrorMessage( RESTRICTION_VIOLATION_ERROR_CODE, 'Sum of places is bigger than maximum of available {} in-places' .format(i)) in_places.append(None if in_max_places is None else in_max_places - cur_sum) return in_places
def _get_avail_out_places(layout): out_of_order = layout.out_of_order layout_data = layout.data height = layout_data.shape[0] width = layout.width out_of_order_places = [0] * height for data_list in out_of_order: for i, amount, _ in data_list: out_of_order_places[i] += amount out_places = [] for i in range(height): cur_sum = 0 for j in range(width): cur_idx = get_layout_col(j) cur_req_idx = get_required_col(j) if layout_data[cur_req_idx][i]: cur_sum += layout_data[cur_idx][i] cur_sum += out_of_order_places[i] out_max_places = layout_data[layout_config.OUT_PLACES_COL][i] if out_max_places is not None and cur_sum > out_max_places: raise ErrorMessage( RESTRICTION_VIOLATION_ERROR_CODE, 'Sum of places is bigger than maximum of available {} out-places' .format(i)) out_places.append(None if out_max_places is None else out_max_places - cur_sum) return out_places
def _null_prev_day_values(layout: Layout, last_update: str = None): null_by_date = pd.Timestamp.now( ) if last_update is None else pd.Timestamp.strptime( last_update, DATE_FORMAT) required_idxs = [[] for _ in range(layout.width)] for i in range(layout.data.shape[0]): if pd.isnull(layout.data[layout_config.IN_PLACES_COL][i]): continue current_idx = i % layout.width now_delta = (null_by_date - layout.data[layout_config.IN_DATES_COL][i]).days if now_delta <= 0: break for j in range(i, min(i + layout.max_days + 1, layout.data.shape[0])): delta = (layout.data[layout_config.OUT_DATES_COL][j] - layout.data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if pd.isnull(layout.data[layout_config.OUT_PLACES_COL][j]): continue required = layout.data[get_required_col(current_idx)][j] if not required: required_idxs[current_idx].append(j) for i in range(layout.width): layout.data[get_required_col(i)][required_idxs[i]] = True layout.data[get_layout_col(i)][required_idxs[i]] = 0
def _find_in_dates_to_remove_losses(layout: Layout, available_in_places): layout_data = layout.data height = layout_data.shape[0] width = layout.width losses = [] cur_vertex_idx = 0 for i in range(height): if pd.isnull(layout_data[layout_config.IN_PLACES_COL][i]): continue cur_sum = 0 cur_idx = i % width for j in range(i, min(i + layout.max_days + 1, height)): delta = (layout_data[layout_config.OUT_DATES_COL][j] - layout_data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if not layout_data[get_required_col(cur_idx)][j] and not pd.isnull(layout_data[get_layout_col(cur_idx)][j]): cur_sum += int(layout_data[get_layout_col(cur_idx)][j]) in_max_places = available_in_places[i] if in_max_places is not None and cur_sum > in_max_places: raise ErrorMessage(RESTRICTION_VIOLATION_ERROR_CODE, 'Sum of places is bigger than maximum of available {} in-places'.format(i)) if in_max_places is not None and in_max_places - cur_sum > 0 and layout.no_losses[i][0]: losses.append((cur_vertex_idx, int(in_max_places - cur_sum))) cur_vertex_idx += 1 return losses
def _get_restrictions(layout, vars_num, avail_in_places, avail_out_places): height = layout.data.shape[0] data = layout.data boundary_inequalities = [] out_inequalities = {} cur_var_idx = 0 for i, avail_in_places in zip(range(height), avail_in_places): column_idx = i % layout.width if avail_in_places is None: continue cur_req_idx = get_required_col(column_idx) cur_col_idx = get_layout_col(column_idx) to_add_idx = [] for j in range(i, min(i + param_config.MAX_DAYS + 1, height)): delta = (data[layout_config.OUT_DATES_COL][j] - data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if data[cur_req_idx][j]: continue to_add_idx.append(cur_var_idx) _add_horizontal_restriction(out_inequalities, j, vars_num, cur_var_idx, avail_out_places[j]) _add_lb_restriction(boundary_inequalities, cur_var_idx, vars_num, data[cur_col_idx][j]) cur_var_idx += 1 if len(to_add_idx) > 0: _add_ub_vertical_restriction(boundary_inequalities, to_add_idx, vars_num, avail_in_places) for key in out_inequalities: boundary_inequalities.append(out_inequalities[key]) boundary_inequalities = np.array(boundary_inequalities) return boundary_inequalities
def _convert_to_out_graph(layout: Layout, available_in_places, corrected_relations): # 0 -> no edge # required -> no edge height = layout.data.shape[0] layout_data = layout.data vertexes = [] vertex_ids = [None for _ in range(height)] for i in range(height): if pd.isnull(layout_data[layout_config.OUT_PLACES_COL][i]): continue vertex_ids[i] = len(vertexes) vertexes.append(Vertex(i, layout.no_losses[i][1], layout_data[layout_config.OUT_DATES_COL][i])) edges = [[] for _ in range(len(vertexes))] in_edges = [[] for _ in range(len(vertexes))] for i in range(height): if pd.isnull(layout_data[layout_config.IN_PLACES_COL][i]): continue cur_idx = i % layout.width for j in range(i, min(i + layout.max_days + 1, height)): if vertex_ids[j] is None: continue delta = (layout_data[layout_config.OUT_DATES_COL][j] - layout_data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if layout_data[get_required_col(cur_idx)][j] or pd.isnull(layout_data[get_layout_col(cur_idx)][j]): continue from_relation = corrected_relations[i][delta - layout.min_days] for k in range(1, min(layout.width + 1, height - j)): delta2 = (layout_data[layout_config.OUT_DATES_COL][j + k] - layout_data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta2) or vertex_ids[j + k] is None: continue if delta2 < layout.min_days or delta2 > layout.max_days: break to_relation = corrected_relations[i][delta2 - layout.min_days] if layout_data[get_required_col(cur_idx)][j + k] or pd.isnull(layout_data[get_layout_col(cur_idx)][j + k]): continue edge = Edge(vertex_ids[j + k], vertex_ids[j], i, layout_data[get_layout_col(cur_idx)][j + k], layout_data[get_layout_col(cur_idx)][j], from_relation, to_relation, available_in_places[i], available_in_places[i]) edges[vertex_ids[j + k]].append(edge) in_edges[vertex_ids[j]].append(edge) return Graph(vertexes, edges, in_edges)
def _fill_empty_layout(layout, width): height = layout[layout_config.IN_PLACES_COL].shape[0] current_idx = 0 for i in range(height): max_places = layout[layout_config.IN_PLACES_COL][i] #layout[get_layout_col(current_idx)][i] = max_places for j in range(i, min(i + param_config.MAX_DAYS + 1, height)): delta = (layout[layout_config.OUT_DATES_COL][j] - layout[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < param_config.MIN_DAYS: continue if delta > param_config.MAX_DAYS: break layout[get_layout_col(current_idx)][j] = 5 break current_idx = (current_idx + 1) % width
def _init_data_frame(layout: Layout, in_dates: list, in_places: list, out_dates: list, out_places: list): data = pd.DataFrame() data[IN_DATES_COL] = np.array(in_dates) data[IN_PLACES_COL] = np.array(in_places) for i in range(layout.width): data = data.assign( **{get_layout_col(i): data[IN_PLACES_COL].apply(lambda _: None)}) data[OUT_DATES_COL] = np.array(out_dates) data[OUT_PLACES_COL] = np.array(out_places) for i in range(layout.width): data = data.assign( ** {get_required_col(i): data[IN_PLACES_COL].apply(lambda _: False)}) return data
def from_layout(layout_obj: core_layout.Layout): data = layout_obj.data height = data.shape[0] dates = [ DatesData(ts_to_str(data[IN_DATES_COL][i]), fl_to_int(data[IN_PLACES_COL][i]), fl_to_int(data[IN_PLACES_COL][i]), ts_to_str(data[OUT_DATES_COL][i]), fl_to_int(data[OUT_PLACES_COL][i]), fl_to_int(data[OUT_PLACES_COL][i]), layout_obj.no_losses[i][0], layout_obj.no_losses[i][1], layout_obj.date_relations[i]) for i in range(height) ] places = [] current_idx = 0 for i in range(height): for j in range(i, min(i + layout_obj.max_days + 1, height)): delta = (data[OUT_DATES_COL][j] - data[IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout_obj.min_days: continue if delta > layout_obj.max_days: break places.append( PlacesData(i, j, fl_to_int(data[get_layout_col(current_idx)][j]), bool(data[get_required_col(current_idx)][j]))) current_idx = (current_idx + 1) % layout_obj.width out_of_order = [] for i, out_of_order_list in enumerate(layout_obj.out_of_order): out_of_order += [ OutOfOrderPlacesData(i, *data) for data in out_of_order_list ] for place in places: dates[place.in_date].in_losses -= place.amount dates[place.out_date].out_losses -= place.amount for ooo in out_of_order: dates[ooo.in_date].in_losses -= ooo.amount dates[ooo.out_date].out_losses -= ooo.amount return LayoutData(layout_obj.id, layout_obj.name, places, dates, layout_obj.width, layout_obj.min_days, layout_obj.max_days, layout_obj.relations, out_of_order, layout_obj.duration_limit, layout_obj.update_date)
def _get_corrected_relations(layout, i, height, column_idx): data = layout.data max_places = data[layout_config.IN_PLACES_COL][i] if max_places is None: return max_places, None, [], 0 _check_ooo_durations(layout, i) cur_idx = get_layout_col(column_idx) cur_req_idx = get_required_col(column_idx) relations = layout.relations if layout.date_relations[ i] is None else layout.date_relations[i] relations_sum = 0 used_sum = sum((amount for _, amount, _ in layout.out_of_order[i])) if len( layout.out_of_order[i]) > 0 else 0 vars_num = 0 for j in range(i, min(i + param_config.MAX_DAYS + 1, height)): delta = (data[layout_config.OUT_DATES_COL][j] - data[layout_config.IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout.min_days: continue if delta > layout.max_days: break if not data[cur_req_idx][j]: vars_num += 1 relations_sum += relations[delta - layout.min_days] else: used_sum += data[cur_idx][j] if relations_sum > 0: coef = 1. / relations_sum else: coef = 0 corrected_relations = [rel * coef for rel in relations] if used_sum > max_places: raise ErrorMessage( RESTRICTION_VIOLATION_ERROR_CODE, 'Sum of places is bigger than maximum of available {} in-places'. format(i)) else: avail_places = max_places - used_sum return max_places, avail_places, corrected_relations, vars_num
def _fill_places_data(layout: Layout, in_places_idxs: dict, out_places_idxs: dict, data: pd.DataFrame): places = PlacesNumber.objects.filter(layout=layout).order_by('in_max_places_id', 'out_max_places_id') \ .select_related('in_max_places', 'out_max_places') col_idxs = {} values = {} required = {} for pl in places: i = in_places_idxs[pl.in_max_places_id] % layout.width j = out_places_idxs[pl.out_max_places_id] if i not in col_idxs: col_idxs[i] = [] values[i] = [] required[i] = [] col_idxs[i].append(j) values[i].append(pl.amount) required[i].append(pl.required) # data[get_layout_col(i)][j] = pl.amount for i in col_idxs: col_vals = np.array(values[i]) col_reqs = np.array(required[i]) data[get_layout_col(i)][col_idxs[i]] = col_vals data[get_required_col(i)][col_idxs[i]] = col_reqs
def generate_layout(initial_data_filename, min_days, max_days, duration_limit, relations, width, name, id): initial_data = read_excel(initial_data_filename) # layout = pd.DataFrame() try: layout = _get_layout_data_from_file(initial_data, name) # layout[layout_config.IN_DATES_COL] = initial_data[init_config.IN_DATES_COL] # layout[layout_config.IN_PLACES_COL] = initial_data[init_config.IN_PLACES_COL] for i in range(width): layout = layout.assign(**{get_layout_col(i): layout[layout_config.IN_PLACES_COL].apply(lambda _: None)}) # layout[layout_config.OUT_PLACES_COL] = initial_data[init_config.OUT_PLACES_COL] # layout[layout_config.OUT_DATES_COL] = initial_data[init_config.OUT_DATES_COL] for i in range(width): layout = layout.assign(**{get_required_col(i): layout[layout_config.IN_PLACES_COL].apply(lambda _: False)}) date_relations = [None for _ in layout[layout_config.IN_DATES_COL]] out_of_order = [[] for _ in layout[layout_config.IN_DATES_COL]] no_losses = [[False, False] for _ in layout[layout_config.IN_DATES_COL]] except KeyError: raise WRONG_EXCEL_FORMAT_ERROR layout_obj = Layout(name, layout, date_relations, out_of_order, None, no_losses, duration_limit=duration_limit, width=width, max_days=max_days, min_days=min_days, relations=relations, id=id) return layout_obj
def _find_out_dates_to_remove_losses(layout: Layout, available_out_places): layout_data = layout.data height = layout_data.shape[0] width = layout.width losses = [] cur_vertex_idx = 0 for i in range(height): if pd.isnull(layout_data[layout_config.OUT_PLACES_COL][i]): continue cur_sum = 0 for j in range(width): cur_idx = get_layout_col(j) cur_req_idx = get_required_col(j) if pd.isnull(layout_data[cur_idx][i]) or layout_data[cur_req_idx][i]: continue cur_sum += int(layout_data[cur_idx][i]) out_max_places = available_out_places[i] if out_max_places is not None and cur_sum > out_max_places: raise ErrorMessage(RESTRICTION_VIOLATION_ERROR_CODE, 'Sum of places is bigger than maximum of available {} out-places'.format(i)) if out_max_places is not None and out_max_places - cur_sum > 0 and layout.no_losses[i][1]: losses.append((cur_vertex_idx, int(out_max_places - cur_sum))) cur_vertex_idx += 1 return losses
def _save_places_number(layout_obj: core_layout.Layout, layout: Layout, in_dates_ids: list, out_dates_ids: list): places_to_create = [] current_idx = 0 for i in range(layout_obj.data.shape[0]): for j in range( i, min(i + layout_obj.max_days + 1, layout_obj.data.shape[0])): delta = (layout_obj.data[OUT_DATES_COL][j] - layout_obj.data[IN_DATES_COL][i]).days if np.isnan(delta) or delta < layout_obj.min_days: continue if delta > layout_obj.max_days: break amount = layout_obj.data[get_layout_col(current_idx)][j] amount = None if pd.isnull(amount) else int(amount) if amount is None: continue places = PlacesNumber(amount=amount, layout=layout, in_max_places_id=in_dates_ids[i], out_max_places_id=out_dates_ids[j]) places_to_create.append(places) current_idx = (current_idx + 1) % layout.width PlacesNumber.objects.bulk_create(places_to_create)
def _update_layout(layout: Layout, new_values: dict): for i, vals in new_values.items(): layout.data[get_layout_col(i)][list(vals.keys())] = list(vals.values())
def _update_out_new_values(layout: Layout, graph: Graph, path: EdgeList, new_values): for edge in path: if graph.vertexes[edge.from_v].row not in new_values[edge.row % layout.width]: new_values[edge.row % layout.width][graph.vertexes[edge.from_v].row] = int(layout.data[get_layout_col(edge.row % layout.width)][graph.vertexes[edge.from_v].row]) if graph.vertexes[edge.to_v].row not in new_values[edge.row % layout.width]: new_values[edge.row % layout.width][graph.vertexes[edge.to_v].row] = int(layout.data[get_layout_col(edge.row % layout.width)][graph.vertexes[edge.to_v].row]) new_values[edge.row % layout.width][graph.vertexes[edge.from_v].row] += 1 new_values[edge.row % layout.width][graph.vertexes[edge.to_v].row] -= 1
def to_layout(self): in_dates = [] in_places = [] out_dates = [] out_places = [] date_priorities = [] no_losses = [] for date in self.dates: in_dates.append(str_to_ts(date.in_date)) in_places.append(date.in_amount) out_dates.append(str_to_ts(date.out_date)) out_places.append(date.out_amount) no_losses.append([date.in_no_losses, date.out_no_losses]) date_priorities.append(date.priorities) data = pd.DataFrame() data[IN_DATES_COL] = np.array(in_dates) data[IN_PLACES_COL] = np.array(in_places) for i in range(self.width): data = data.assign( ** {get_layout_col(i): data[IN_PLACES_COL].apply(lambda _: None)}) data[OUT_DATES_COL] = np.array(out_dates) data[OUT_PLACES_COL] = np.array(out_places) for i in range(self.width): data = data.assign(**{ get_required_col(i): data[IN_PLACES_COL].apply(lambda _: False) }) col_idxs = {} values = {} required = {} for pl in self.places: i = pl.in_date % self.width j = pl.out_date if i not in col_idxs: col_idxs[i] = [] values[i] = [] required[i] = [] col_idxs[i].append(j) values[i].append(pl.amount) required[i].append(pl.required) # data[get_layout_col(i)][j] = pl.amount for i in col_idxs: col_vals = np.array(values[i]) col_reqs = np.array(required[i]) data[get_layout_col(i)][col_idxs[i]] = col_vals data[get_required_col(i)][col_idxs[i]] = col_reqs out_of_order = [[] for _ in data[IN_DATES_COL]] for ooo_data in self.out_of_order: out_of_order[ooo_data.in_date].append( (ooo_data.out_date, ooo_data.amount, ooo_data.auto_changed)) layout_obj = core_layout.Layout(self.name, data, date_priorities, out_of_order, self.update_from_file_date, no_losses, self.width, self.min_days, self.max_days, self.duration_limit, self.priorities, self.id) return layout_obj