Untitled
class Worker: def __init__(self, worker_id, position, compensation): self.worker_id = worker_id self.position = position self.compensation = compensation self.total_time = 0 self.current_entry_time = None # Tracks the last entry time (if currently in office) self.promotions = [] # List of promotions (each as a tuple of (timestamp, position, compensation)) def promote(self, new_position, new_compensation, start_timestamp): self.promotions.append((start_timestamp, new_position, new_compensation)) def get_current_compensation(self, timestamp): # Find the most recent promotion before or at the given timestamp for start_timestamp, position, compensation in reversed(self.promotions): if timestamp >= start_timestamp: return compensation return self.compensation # Default to the initial compensation class WorkingHoursRegister: def __init__(self): self.workers = {} self.double_pay_periods = [] # List of double pay periods (each as a tuple of (startTimestamp, endTimestamp)) def add_worker(self, worker_id, position, compensation): if worker_id in self.workers: return "false" self.workers[worker_id] = Worker(worker_id, position, compensation) return "true" def register(self, worker_id, timestamp): if worker_id not in self.workers: return "invalid_request" worker = self.workers[worker_id] if worker.current_entry_time is None: # The worker is entering the office worker.current_entry_time = timestamp else: # The worker is leaving the office time_spent = timestamp - worker.current_entry_time worker.total_time += time_spent worker.current_entry_time = None return "registered" def get(self, worker_id): if worker_id not in self.workers: return "" worker = self.workers[worker_id] return str(worker.total_time) def top_n_workers(self, n, position): # Filter workers by position filtered_workers = [worker for worker in self.workers.values() if worker.position == position] # Sort by total time in descending order and by worker_id in ascending order for ties filtered_workers.sort(key=lambda worker: (-worker.total_time, worker.worker_id)) # Prepare the result string top_workers = filtered_workers[:n] result = ", ".join([f"{worker.worker_id}({worker.total_time})" for worker in top_workers]) return result def promote(self, worker_id, new_position, new_compensation, start_timestamp): if worker_id not in self.workers: return "invalid_request" worker = self.workers[worker_id] # Check if the worker has already been promoted to this position after or at the start_timestamp if worker.promotions and worker.promotions[-1][0] >= start_timestamp: return "invalid_request" worker.promote(new_position, new_compensation, start_timestamp) return "success" def calc_salary(self, worker_id, start_timestamp, end_timestamp): if worker_id not in self.workers: return "" worker = self.workers[worker_id] total_salary = 0 for promotion in worker.promotions: promotion_timestamp, position, compensation = promotion session_start = max(start_timestamp, promotion_timestamp) if worker.current_entry_time and worker.current_entry_time < end_timestamp: session_end = min(end_timestamp, worker.current_entry_time) if session_start < session_end: total_salary += self.calculate_salary_with_double_pay(worker, session_start, session_end) return str(total_salary) def calculate_salary_with_double_pay(self, worker, start_time, end_time): # Calculate salary with consideration for double pay periods salary = 0 remaining_start = start_time for period_start, period_end in self.double_pay_periods: if period_end <= start_time or period_start >= end_time: continue if period_start > remaining_start: salary += (period_start - remaining_start) * worker.get_current_compensation(remaining_start) remaining_start = period_start if period_end <= end_time: salary += (period_end - remaining_start) * worker.get_current_compensation(remaining_start) * 2 remaining_start = period_end else: salary += (end_time - remaining_start) * worker.get_current_compensation(remaining_start) * 2 remaining_start = end_time break if remaining_start < end_time: salary += (end_time - remaining_start) * worker.get_current_compensation(remaining_start) return salary def set_double_pay_period(self, start_timestamp, end_timestamp): self.double_pay_periods.append((start_timestamp, end_timestamp)) return "double_pay_period_set" def process_queries(queries): register = WorkingHoursRegister() results = [] for query in queries: operation = query.split() if operation[0] == "ADD_WORKER": worker_id = operation[1] position = operation[2] compensation = int(operation[3]) result = register.add_worker(worker_id, position, compensation) elif operation[0] == "REGISTER": worker_id = operation[1] timestamp = int(operation[2]) result = register.register(worker_id, timestamp) elif operation[0] == "GET": worker_id = operation[1] result = register.get(worker_id) elif operation[0] == "TOP_N_WORKERS": n = int(operation[1]) position = operation[2] result = register.top_n_workers(n, position) elif operation[0] == "PROMOTE": worker_id = operation[1] new_position = operation[2] new_compensation = int(operation[3]) start_timestamp = int(operation[4]) result = register.promote(worker_id, new_position, new_compensation, start_timestamp) elif operation[0] == "CALC_SALARY": worker_id = operation[1] start_timestamp = int(operation[2]) end_timestamp = int(operation[3]) result = register.calc_salary(worker_id, start_timestamp, end_timestamp) elif operation[0] == "SET_DOUBLE_PAY_PERIOD": start_timestamp = int(operation[1]) end_timestamp = int(operation[2]) result = register.set_double_pay_period(start_timestamp, end_timestamp) results.append(result) return results # Example usage: queries = [ "ADD_WORKER John Engineer 1000", "REGISTER John 10", "REGISTER John 60", "PROMOTE John SeniorEngineer 2000 70", "REGISTER John 100", "CALC_SALARY John 0 100", "PROMOTE John Manager 3000 150", "REGISTER John 160", "REGISTER John 200", "SET_DOUBLE_PAY_PERIOD 50 120", "CALC_SALARY John 0 200" ]
Leave a Comment