From 9ee6d5d5da28d76f54b8e25ee773fdcf4498de53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Mon, 30 Jun 2025 16:49:53 -0300 Subject: [PATCH] =?UTF-8?q?DevTest=20Daniel=20C=C3=A1ceres?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .../Elevator_Prediction_System_Design.pdf | Bin 0 -> 122296 bytes elevator_system/README.md | 111 +++++++ elevator_system/demo.py | 278 ++++++++++++++++++ .../instance/elevator_prediction.db | Bin 0 -> 16384 bytes elevator_system/main.py | 196 ++++++++++++ elevator_system/requirements.txt | 5 + elevator_system/schema.sql | 60 ++++ elevator_system/test_elevator.py | 274 +++++++++++++++++ 9 files changed, 927 insertions(+) create mode 100644 .gitignore create mode 100644 elevator_system/Elevator_Prediction_System_Design.pdf create mode 100644 elevator_system/README.md create mode 100644 elevator_system/demo.py create mode 100644 elevator_system/instance/elevator_prediction.db create mode 100644 elevator_system/main.py create mode 100644 elevator_system/requirements.txt create mode 100644 elevator_system/schema.sql create mode 100644 elevator_system/test_elevator.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..688988d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +elevator_system/__pycache__/main.cpython-312.pyc +elevator_system/__pycache__/test_elevator.cpython-312-pytest-7.4.4.pyc +elevator_system/__pycache__/test_elevator.cpython-312-pytest-8.4.1.pyc diff --git a/elevator_system/Elevator_Prediction_System_Design.pdf b/elevator_system/Elevator_Prediction_System_Design.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3ec0d0843517b652a8a9b240755b72f5fbf52a78 GIT binary patch literal 122296 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 literal 0 HcmV?d00001 diff --git a/elevator_system/README.md b/elevator_system/README.md new file mode 100644 index 0000000..36b7e69 --- /dev/null +++ b/elevator_system/README.md @@ -0,0 +1,111 @@ +# Elevator Prediction System + +A focused system for collecting elevator data to train ML models that predict optimal resting floors. + +## Overview + +This system implements the **"Golden Event"** approach for elevator prediction: +- **Core Concept**: When an elevator is resting on floor X at time T, and the next call comes from floor Y +- **ML Goal**: Predict the most likely call floor based on current resting floor and time +- **Data Design**: Single table capturing the critical resting→call relationship + +## The Golden Event + +The system focuses on capturing the most important data point for ML prediction: + +``` +Elevator resting on floor X at time T → Next call from floor Y +``` + +This relationship is logged in the `demand_log` table with all the features needed for ML training. + +## Database Schema + +### DemandLog Table (Single Table Design) + +| Column | Type | ML Purpose | +|--------|------|------------| +| id | Integer | Primary key | +| timestamp_rested | DateTime | **Feature**: When elevator became idle | +| timestamp_called | DateTime | **Feature**: When next call was received | +| resting_floor | Integer | **Feature**: Floor elevator was resting on | +| call_floor | Integer | **Label**: Floor the call came from | +| destination_floor | Integer | **Feature**: Where user wants to go | +| day_of_week | Integer | **Feature**: Day of week (0-6) | +| hour_of_day | Integer | **Feature**: Hour of day (0-23) | + +## API Endpoints + +### POST /call +Call the elevator from a floor (triggers golden event logging if elevator is resting). + +### POST /step +Advance simulation by one time unit. + +### GET /status +Get current elevator status and total logs. + +### GET /logs +Get demand logs for ML training. + +### GET /stats +Get statistics for ML insights. + +## Installation + +1. **Install dependencies:** +```bash +pip install -r requirements.txt +``` + +2. **Run the application:** +```bash +python main.py +``` +The server will start on `http://localhost:5000` + +### Running Tests + +```bash +python -m pytest test_elevator.py -v +``` + +### Running the Demo + +```bash +python demo.py +``` + +The demo simulates a typical office building day and shows: +- Golden event capture +- ML data analysis + +## ML Training Data + +The system generates perfect training data for ML models: + +### Features (X): +- `resting_floor`: Current resting floor +- `timestamp_rested`: When elevator became idle +- `day_of_week`: Day of the week (0-6) +- `hour_of_day`: Hour of the day (0-23) +- `destination_floor`: Where user wants to go (optional) + +### Label (y): +- `call_floor`: The floor the next call comes from + +### Example ML Use Cases: +- **Classification**: Predict most likely call floor +- **Regression**: Predict call probability for each floor +- **Time Series**: Predict call patterns over time + +## Key Design Principles + +1. **Focus on Golden Event**: Only log when elevator is resting and receives a call +2. **Discrete Time**: Step-based simulation for predictability and testing +3. **Single Table**: All ML data in one optimized table +4. **Time Features**: Automatic extraction of day_of_week and hour_of_day +5. **Simple API**: Minimal endpoints for simulation control + +## Final notes +I have included the PDF "Elevator_Prediction_System_Design.pdf" explaining my proposed solution. \ No newline at end of file diff --git a/elevator_system/demo.py b/elevator_system/demo.py new file mode 100644 index 0000000..b6d9fce --- /dev/null +++ b/elevator_system/demo.py @@ -0,0 +1,278 @@ +#!/usr/bin/env python3 +""" +Elevator Prediction System Demo +This script demonstrates the ML-focused elevator system that captures the "golden event". +""" + +import requests +import time +import random + +BASE_URL = "http://localhost:5000" + +def call_elevator(floor, destination_floor=None): + """Call the elevator from a specific floor""" + data = {'floor': floor} + if destination_floor: + data['destination_floor'] = destination_floor + + response = requests.post(f"{BASE_URL}/call", json=data) + if response.status_code == 201: + return response.json() + else: + print(f"Error calling elevator: {response.text}") + return None + +def step_simulation(): + """Advance the simulation by one time unit""" + response = requests.post(f"{BASE_URL}/step") + if response.status_code == 200: + return response.json() + else: + print(f"Error stepping simulation: {response.text}") + return None + +def get_status(): + """Get current elevator status""" + response = requests.get(f"{BASE_URL}/status") + if response.status_code == 200: + return response.json() + else: + print(f"Error getting status: {response.text}") + return None + +def get_logs(): + """Get demand logs for ML training""" + response = requests.get(f"{BASE_URL}/logs") + if response.status_code == 200: + return response.json() + else: + print(f"Error getting logs: {response.text}") + return None + +def get_stats(): + """Get statistics for ML insights""" + response = requests.get(f"{BASE_URL}/stats") + if response.status_code == 200: + return response.json() + else: + print(f"Error getting stats: {response.text}") + return None + +def simulate_elevator_cycle(call_floor, destination_floor): + """Simulate a complete elevator cycle""" + print(f"\n=== Elevator Cycle ===") + print(f"Call from floor: {call_floor}") + print(f"Destination: {destination_floor}") + + # 1. Call the elevator + result = call_elevator(call_floor, destination_floor) + + # 2. Step simulation until elevator reaches call floor + current_floor = result['elevator_state']['current_floor'] # Get actual elevator position from state + print(f"Current floor: {current_floor}") + ini_current_floor = current_floor + # If elevator is already at call floor, we need one step to "arrive" there + if current_floor == call_floor: + step_result = step_simulation() + print(f"Step result (arriving at call floor)...") + current_floor = step_result['elevator_state']['current_floor'] + else: + # Step until elevator reaches call floor + while current_floor != call_floor: + step_result = step_simulation() + # print(f"Step result (until call floor): {step_result}") + if step_result and step_result['moved']: + current_floor = step_result['elevator_state']['current_floor'] + print(f"Moved to floor {current_floor} (until call floor)") + else: + # Elevator arrived at call floor + current_floor = step_result['elevator_state']['current_floor'] + if current_floor == call_floor: + print(f"Arrived at call floor {current_floor}") + break + + # 3. Step simulation until elevator reaches destination + # First, ensure we've properly arrived at the call floor + if current_floor == call_floor: + # Take one more step to ensure the elevator has processed the call floor arrival + step_result = step_simulation() + print(f"Step result (processing call floor arrival)...") + current_floor = step_result['elevator_state']['current_floor'] + if ini_current_floor == call_floor: + print(f"Moved to floor {current_floor} (until destination floor)") + # Now step until we reach the destination + while current_floor != destination_floor: + step_result = step_simulation() + # print(f"Step result (until destination floor): {step_result}") + if step_result and step_result['moved']: + current_floor = step_result['elevator_state']['current_floor'] + print(f"Moved to floor {current_floor} (until destination floor)") + else: + # Elevator arrived at destination or stopped + current_floor = step_result['elevator_state']['current_floor'] + if current_floor == destination_floor: + print(f"Arrived at destination floor {current_floor}") + break + + # 4. Final step to arrive and start resting + step_result = step_simulation() + if step_result: + print(f"Arrived and started resting") + + return current_floor + +def simulate_office_building(): + """Simulate a typical office building day""" + print("=== Office Building Elevator Simulation ===") + + floors = list(range(1, 11)) # 10 floors + + # Morning rush hour (8-9 AM) - people coming to work + print("\n--- Morning Rush Hour (8-9 AM) ---") + for i in range(6): + # Most people come from ground floor to various floors + destination_floor = random.choice(floors[1:]) # Not ground floor + simulate_elevator_cycle(1, destination_floor) + time.sleep(0.1) # Small delay between cycles + + # Mid-morning (9-11 AM) - some movement between floors + print("\n--- Mid-Morning (9-11 AM) ---") + for i in range(2): + call_floor = random.choice(floors) + destination_floor = random.choice([f for f in floors if f != call_floor]) + simulate_elevator_cycle(call_floor, destination_floor) + time.sleep(0.1) + + # Lunch time (12-1 PM) - people going to cafeteria (floor 2) + print("\n--- Lunch Time (12-1 PM) ---") + for i in range(4): + call_floor = random.choice(floors) + simulate_elevator_cycle(call_floor, 2) # Cafeteria floor + time.sleep(0.1) + + # After lunch (1-2 PM) - people returning to their floors + print("\n--- After Lunch (1-2 PM) ---") + for i in range(4): + destination_floor = random.choice(floors[1:]) # To various floors + simulate_elevator_cycle(2, destination_floor) # From cafeteria + time.sleep(0.1) + + # Afternoon (2-5 PM) - some movement + print("\n--- Afternoon (2-5 PM) ---") + for i in range(2): + call_floor = random.choice(floors) + destination_floor = random.choice([f for f in floors if f != call_floor]) + simulate_elevator_cycle(call_floor, destination_floor) + time.sleep(0.1) + + # Evening rush (5-6 PM) - people leaving work + print("\n--- Evening Rush (5-6 PM) ---") + for i in range(6): + call_floor = random.choice(floors[1:]) # From various floors + simulate_elevator_cycle(call_floor, 1) # To ground floor + time.sleep(0.1) + +def analyze_ml_data(): + """Analyze the collected data for ML insights""" + print("\n=== ML Data Analysis ===") + + # Get logs + logs_data = get_logs() + if not logs_data: + return + + logs = logs_data['logs'] + print(f"\nTotal golden events captured: {len(logs)}") + + if len(logs) == 0: + print("No data collected yet. Run some simulation first.") + return + + # Analyze resting floor patterns + resting_floor_counts = {} + call_floor_counts = {} + + for log in logs: + resting_floor = log['resting_floor'] + call_floor = log['call_floor'] + + resting_floor_counts[resting_floor] = resting_floor_counts.get(resting_floor, 0) + 1 + call_floor_counts[call_floor] = call_floor_counts.get(call_floor, 0) + 1 + + print("\nResting Floor Analysis:") + for floor, count in sorted(resting_floor_counts.items()): + print(f" Floor {floor}: {count} times") + + print("\nCall Floor Analysis:") + for floor, count in sorted(call_floor_counts.items()): + print(f" Floor {floor}: {count} calls") + + # Find most common call floor + if call_floor_counts: + most_common_call_floor = max(call_floor_counts, key=call_floor_counts.get) + print(f"\nMost common call floor: {most_common_call_floor} ({call_floor_counts[most_common_call_floor]} calls)") + + # Analyze time patterns + hour_counts = {} + for log in logs: + hour = log['hour_of_day'] + hour_counts[hour] = hour_counts.get(hour, 0) + 1 + + print("\nHourly Call Patterns:") + for hour in sorted(hour_counts.keys()): + print(f" {hour:02d}:00: {hour_counts[hour]} calls") + + # Get statistics + stats = get_stats() + if stats and stats['resting_patterns']: + print("\nResting → Call Patterns:") + for pattern in stats['resting_patterns'][:5]: # Show top 5 + print(f" Resting on {pattern['resting_floor']} → Call from {pattern['call_floor']}: {pattern['count']} times") + +def main(): + """Main demonstration function""" + print("Starting Elevator Prediction System Demo") + print("Make sure the system is running on http://localhost:5000") + + # Check if system is running + try: + status = get_status() + if status: + print("Elevator system is running") + print(f"Current logs: {status['total_logs']}") + else: + print("Elevator system is running (no activity yet)") + except requests.exceptions.ConnectionError: + print("Error: Cannot connect to elevator system") + print("Please start the system with: python main.py") + return + + # Run simulation + simulate_office_building() + + # Analyze data + analyze_ml_data() + + # Show final status + final_status = get_status() + if final_status: + print(f"\nFinal elevator state:") + elevator_state = final_status['elevator'] + print(f" Current floor: {elevator_state['current_floor']}") + print(f" Is resting: {elevator_state['is_resting']}") + print(f" Direction: {elevator_state['direction']}") + print(f" Total golden events: {final_status['total_logs']}") + + print("\nDemo completed!") + print("The collected data can now be used to train ML models for optimal resting floor prediction.") + print("\nKey ML Features Collected:") + print(" - resting_floor: Where elevator was idle") + print(" - call_floor: Where the next call came from") + print(" - timestamp_rested: When elevator became idle") + print(" - timestamp_called: When call was received") + print(" - day_of_week: Day of the week (0-6)") + print(" - hour_of_day: Hour of the day (0-23)") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/elevator_system/instance/elevator_prediction.db b/elevator_system/instance/elevator_prediction.db new file mode 100644 index 0000000000000000000000000000000000000000..6ea5f220cdb1c98c731919a886fc65a0e08c740d GIT binary patch literal 16384 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 next_floor: + self.direction = 'down' + self.current_floor -= 1 + else: + # Arrived at destination + self.destination_queue.pop(0) + # Stop here for one step to simulate arrival + if not self.destination_queue: + # No more destinations, start resting + self.start_resting(datetime.now()) + # Always return False when arriving at a destination + # This simulates the elevator stopping to pick up/drop of passengers + return False + + return True + + def reset(self): + """Reset the elevator to its initial state""" + self.current_floor = 1 + self.direction = 'idle' + self.is_resting = True + self.resting_since = datetime.now() + self.destination_queue = [] + +elevator = Elevator() + + +@app.route('/call', methods=['POST']) +def call_elevator(): + data = request.get_json() + + if not data or 'floor' not in data: + return jsonify({'error': 'Floor is required'}), 400 + + call_floor = data['floor'] + destination_floor = data.get('destination_floor') + + elevator.receive_call(call_floor, destination_floor) + + return jsonify({ + 'message': 'Call received', + 'call_floor': call_floor, + 'destination_floor': destination_floor, + 'elevator_state': elevator.get_state() + }), 201 + + +@app.route('/step', methods=['POST']) +def step_simulation(): + moved = elevator.step() + + return jsonify({ + 'message': 'Simulation stepped', + 'moved': moved, + 'elevator_state': elevator.get_state() + }) + + +@app.route('/status', methods=['GET']) +def get_status(): + return jsonify({ + 'elevator': elevator.get_state(), + 'total_logs': DemandLog.query.count() + }) + + +@app.route('/logs', methods=['GET']) +def get_logs(): + limit = request.args.get('limit', 100, type=int) + logs = DemandLog.query.order_by(DemandLog.timestamp_called.desc()).limit(limit).all() + + return jsonify({ + 'logs': [{ + 'id': log.id, + 'timestamp_rested': log.timestamp_rested.isoformat(), + 'timestamp_called': log.timestamp_called.isoformat(), + 'resting_floor': log.resting_floor, + 'call_floor': log.call_floor, + 'destination_floor': log.destination_floor, + 'day_of_week': log.day_of_week, + 'hour_of_day': log.hour_of_day, + 'idle_time_seconds': (log.timestamp_called - log.timestamp_rested).total_seconds() + } for log in logs] + }) + + +@app.route('/stats', methods=['GET']) +def get_stats(): + resting_patterns = db.session.query( + DemandLog.resting_floor, + DemandLog.call_floor, + db.func.count(DemandLog.id).label('count') + ).group_by( + DemandLog.resting_floor, + DemandLog.call_floor + ).order_by( + DemandLog.resting_floor, + db.func.count(DemandLog.id).desc() + ).all() + + return jsonify({ + 'resting_patterns': [ + { + 'resting_floor': r.resting_floor, + 'call_floor': r.call_floor, + 'count': r.count + } for r in resting_patterns + ] + }) + + +if __name__ == '__main__': + with app.app_context(): + db.create_all() + elevator.start_resting(datetime.now()) + app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/elevator_system/requirements.txt b/elevator_system/requirements.txt new file mode 100644 index 0000000..daaffa5 --- /dev/null +++ b/elevator_system/requirements.txt @@ -0,0 +1,5 @@ +Flask==2.3.3 +Flask-SQLAlchemy==3.0.5 +pytest==7.4.3 +pytest-flask==1.3.0 +requests==2.31.0 \ No newline at end of file diff --git a/elevator_system/schema.sql b/elevator_system/schema.sql new file mode 100644 index 0000000..5de27c8 --- /dev/null +++ b/elevator_system/schema.sql @@ -0,0 +1,60 @@ +-- Elevator Prediction System Database Schema +-- Single table design focused on the "Golden Event" for ML training + +CREATE TABLE demand_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp_rested DATETIME NOT NULL, -- When elevator became idle + timestamp_called DATETIME NOT NULL, -- When next call was received + resting_floor INTEGER NOT NULL, -- Floor elevator was resting on + call_floor INTEGER NOT NULL, -- Floor the call came from + destination_floor INTEGER, -- Where user wants to go + day_of_week INTEGER NOT NULL, -- 0-6 (Monday-Sunday) + hour_of_day INTEGER NOT NULL -- 0-23 +); + +-- Create indexes for better query performance +CREATE INDEX idx_demand_log_timestamp_rested ON demand_log(timestamp_rested); +CREATE INDEX idx_demand_log_timestamp_called ON demand_log(timestamp_called); +CREATE INDEX idx_demand_log_resting_floor ON demand_log(resting_floor); +CREATE INDEX idx_demand_log_call_floor ON demand_log(call_floor); +CREATE INDEX idx_demand_log_time_features ON demand_log(day_of_week, hour_of_day); + +-- Example queries for ML data extraction: + +-- 1. Get all training data (features and labels) +SELECT + resting_floor, + day_of_week, + hour_of_day, + destination_floor, + call_floor as label +FROM demand_log +ORDER BY timestamp_called DESC; + +-- 2. Find most common call floor for each resting floor +SELECT + resting_floor, + call_floor, + COUNT(*) as frequency +FROM demand_log +GROUP BY resting_floor, call_floor +ORDER BY resting_floor, frequency DESC; + +-- 3. Analyze time patterns +SELECT + day_of_week, + hour_of_day, + call_floor, + COUNT(*) as call_count +FROM demand_log +GROUP BY day_of_week, hour_of_day, call_floor +ORDER BY day_of_week, hour_of_day, call_count DESC; + +-- 4. Calculate idle time statistics +SELECT + resting_floor, + AVG((julianday(timestamp_called) - julianday(timestamp_rested)) * 24 * 60) as avg_idle_minutes, + COUNT(*) as total_events +FROM demand_log +GROUP BY resting_floor +ORDER BY avg_idle_minutes DESC; \ No newline at end of file diff --git a/elevator_system/test_elevator.py b/elevator_system/test_elevator.py new file mode 100644 index 0000000..1df3174 --- /dev/null +++ b/elevator_system/test_elevator.py @@ -0,0 +1,274 @@ +import pytest +import json +from main import app, db + + +@pytest.fixture +def client(): + app.config['TESTING'] = True + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' + + with app.test_client() as client: + with app.app_context(): + # Drop all tables and recreate them + db.drop_all() + db.create_all() + + # Reset elevator to initial state + from main import elevator + elevator.reset() + yield client + + +def test_call_elevator(client): + """Test calling the elevator""" + response = client.post('/call', json={'floor': 5, 'destination_floor': 10}) + + assert response.status_code == 201 + data = json.loads(response.data) + assert data['message'] == 'Call received' + assert data['call_floor'] == 5 + assert data['destination_floor'] == 10 + + +def test_call_elevator_missing_floor(client): + """Test calling elevator without floor""" + response = client.post('/call', json={}) + assert response.status_code == 400 + + +def test_step_simulation(client): + """Test stepping the simulation""" + # First call the elevator + client.post('/call', json={'floor': 5}) + + # Then step the simulation + response = client.post('/step') + assert response.status_code == 200 + + data = json.loads(response.data) + assert data['message'] == 'Simulation stepped' + assert data['moved'] == True + + +def test_get_status(client): + """Test getting elevator status""" + response = client.get('/status') + assert response.status_code == 200 + + data = json.loads(response.data) + assert 'elevator' in data + assert 'total_logs' in data + assert data['total_logs'] == 0 # No logs yet + + +def test_golden_event_logging(client): + """Test that the golden event is logged when elevator is resting""" + # Elevator starts resting + response = client.get('/status') + data = json.loads(response.data) + assert data['elevator']['is_resting'] == True + + # Call the elevator + client.post('/call', json={'floor': 5, 'destination_floor': 10}) + + # Check that a log entry was created + response = client.get('/logs') + data = json.loads(response.data) + assert len(data['logs']) == 1 + + log = data['logs'][0] + assert log['resting_floor'] == 1 # Started at floor 1 + assert log['call_floor'] == 5 + assert log['destination_floor'] == 10 + assert log['day_of_week'] >= 0 and log['day_of_week'] <= 6 + assert log['hour_of_day'] >= 0 and log['hour_of_day'] <= 23 + + +def test_no_logging_when_not_resting(client): + """Test that no log is created when elevator is not resting""" + # Call elevator (this will log the first call) + client.post('/call', json={'floor': 5}) + + # Step only 2 times - elevator is still moving (at floor 3) + for _ in range(2): + client.post('/step') + + # Call again while elevator is actually moving (not resting) + client.post('/call', json={'floor': 3}) + + # Check logs - should only have 1 entry (the first call) + response = client.get('/logs') + data = json.loads(response.data) + assert len(data['logs']) == 1 + + # Verify the logs + logs = data['logs'] + assert logs[0]['call_floor'] == 5 # First call + + +def test_no_logging_during_movement(client): + """Test that no log is created when elevator is actively moving""" + # Call elevator (this will log the first call) + client.post('/call', json={'floor': 5}) + + # Step once - elevator is moving (at floor 2) + client.post('/step') + + # Verify elevator is not resting + response = client.get('/status') + data = json.loads(response.data) + assert data['elevator']['is_resting'] == False + + # Call again while elevator is definitely moving + client.post('/call', json={'floor': 3}) + + # Check logs - should only have 1 entry (the first call) + response = client.get('/logs') + data = json.loads(response.data) + assert len(data['logs']) == 1 + + +def test_complete_elevator_cycle(client): + """Test a complete elevator cycle with logging""" + # 1. Elevator is resting at floor 1 + response = client.get('/status') + data = json.loads(response.data) + assert data['elevator']['is_resting'] == True + assert data['elevator']['current_floor'] == 1 + + # 2. Call from floor 5 to floor 10 + client.post('/call', json={'floor': 5, 'destination_floor': 10}) + + # 3. Step until elevator reaches floor 5 + for i in range(4): + response = client.post('/step') + data = json.loads(response.data) + print(f"Step {i+1}: moved={data['moved']}, floor={data['elevator_state']['current_floor']}") + assert data['moved'] == True + + # 4. Arrive at floor 5 (should stop) + response = client.post('/step') + data = json.loads(response.data) + print(f"Pick up passengers: moved={data['moved']}, floor={data['elevator_state']['current_floor']}") + assert data['moved'] == False # Stopped at floor 5 to pick up passengers + + # 5. Step until elevator reaches floor 10 + for i in range(5): + response = client.post('/step') + data = json.loads(response.data) + print(f"Step {i+5}: moved={data['moved']}, floor={data['elevator_state']['current_floor']}") + assert data['moved'] == True + + # 6. Arrive at floor 10 and start resting + response = client.post('/step') + data = json.loads(response.data) + print(f"Final step: moved={data['moved']}, floor={data['elevator_state']['current_floor']}") + assert data['moved'] == False # No more destinations. Stopped and resting + + # 7. Check that elevator is resting again + response = client.get('/status') + data = json.loads(response.data) + assert data['elevator']['is_resting'] == True + assert data['elevator']['current_floor'] == 10 + + # 8. Check that we have one log entry + response = client.get('/logs') + data = json.loads(response.data) + assert len(data['logs']) == 1 + + +def test_get_stats(client): + """Test getting statistics""" + # Create some test data + client.post('/call', json={'floor': 5, 'destination_floor': 10}) + client.post('/step') # Move to floor 2 + client.post('/step') # Move to floor 3 + client.post('/step') # Move to floor 4 + client.post('/step') # Move to floor 5 + client.post('/step') # Move to floor 6 + client.post('/step') # Move to floor 7 + client.post('/step') # Move to floor 8 + client.post('/step') # Move to floor 9 + client.post('/step') # Move to floor 10 + client.post('/step') # Arrive and start resting + + # Now call from floor 3 + client.post('/call', json={'floor': 3, 'destination_floor': 7}) + + response = client.get('/stats') + assert response.status_code == 200 + + data = json.loads(response.data) + assert 'resting_patterns' in data + assert len(data['resting_patterns']) > 0 + + +def test_ml_training_data_generation(client): + """Test that the system generates proper ML training data""" + # Simulate multiple elevator cycles to generate training data + floors = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + # Morning pattern: many calls from floor 1 + for i in range(5): + # Ensure elevator is resting before calling + response = client.get('/status') + data = json.loads(response.data) + if not data['elevator']['is_resting']: + # Wait for elevator to finish current journey + while not data['elevator']['is_resting']: + client.post('/step') + response = client.get('/status') + data = json.loads(response.data) + + # Call from floor 1 to various floors + client.post('/call', json={'floor': 1, 'destination_floor': floors[i % len(floors)]}) + + # Move elevator to destination + for _ in range(floors[i % len(floors)] - 1): + client.post('/step') + client.post('/step') # Arrive and rest + + # Afternoon pattern: calls from middle floors + for i in range(3): + # Ensure elevator is resting before calling + response = client.get('/status') + data = json.loads(response.data) + if not data['elevator']['is_resting']: + # Wait for elevator to finish current journey + while not data['elevator']['is_resting']: + client.post('/step') + response = client.get('/status') + data = json.loads(response.data) + + call_floor = floors[2 + (i % 6)] # Floors 3-8 + client.post('/call', json={'floor': call_floor, 'destination_floor': 1}) + + # Move elevator to destination + for _ in range(abs(call_floor - 1)): + client.post('/step') + client.post('/step') # Arrive and rest + + # Get logs for ML training + response = client.get('/logs') + data = json.loads(response.data) + + # Verify we have meaningful training data + assert len(data['logs']) == 8 # 5 morning + 3 afternoon calls + + # Check that floor 1 has the most calls (morning rush) + floor_1_calls = sum(1 for log in data['logs'] if log['call_floor'] == 1) + assert floor_1_calls >= 5 # At least 5 calls from floor 1 + + # Verify all logs have proper ML features + for log in data['logs']: + assert 'resting_floor' in log + assert 'call_floor' in log + assert 'day_of_week' in log + assert 'hour_of_day' in log + assert 'idle_time_seconds' in log + assert log['idle_time_seconds'] > 0 + + +if __name__ == '__main__': + pytest.main([__file__]) \ No newline at end of file