6 Commits

Author SHA1 Message Date
Xuwznln
692b853101 Update bug report template 2025-10-06 14:36:53 +08:00
Xuwznln
4c86816920 Update docs 2025-10-01 18:32:03 +08:00
Xuwznln
349511e00f Bump version: 0.0.3 → 0.0.4 2025-10-01 18:07:21 +08:00
Xuwznln
cbfae640d1 Bump version: 0.0.2 → 0.0.3 2025-10-01 18:00:14 +08:00
Xuwznln
de3fa68fa6 recover version 2025-10-01 18:00:10 +08:00
Xuwznln
78395349b2 Modify pypi package name 2025-10-01 17:59:35 +08:00
9 changed files with 79 additions and 177 deletions

View File

@@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.0.2 current_version = 0.0.4
commit = True commit = True
tag = True tag = True
tag_name = v{new_version} tag_name = v{new_version}

View File

@@ -0,0 +1,30 @@
---
name: Bug Report
about: Report a bug in the project
title: "[BUG] "
labels: bug
assignees: ""
---
**Version Information**
- elevator-py version: [e.g. v0.0.5]
- Python version: [e.g. 3.11]
**Bug Description**
A clear and concise description of the bug
**Steps to Reproduce**
1.
2.
3.
**Expected Behavior**
What you expected to happen
**Actual Behavior**
What actually happened
**Additional Context (Optional)**
Any other information that might help, such as error logs, screenshots, etc.

View File

@@ -2,8 +2,8 @@
<div align="center"> <div align="center">
[![PyPI version](https://badge.fury.io/py/elevatorpy.svg)](https://badge.fury.io/py/elevatorpy) [![PyPI version](https://badge.fury.io/py/elevator-py.svg)](https://badge.fury.io/py/elevator-py)
[![Python versions](https://img.shields.io/pypi/pyversions/elevatorpy.svg)](https://pypi.org/project/elevatorpy/) [![Python versions](https://img.shields.io/pypi/pyversions/elevator-py.svg)](https://pypi.org/project/elevator-py/)
[![Build Status](https://github.com/ZGCA-Forge/Elevator/actions/workflows/ci.yml/badge.svg)](https://github.com/ZGCA-Forge/Elevator/actions) [![Build Status](https://github.com/ZGCA-Forge/Elevator/actions/workflows/ci.yml/badge.svg)](https://github.com/ZGCA-Forge/Elevator/actions)
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen)](https://zgca-forge.github.io/Elevator/) [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-brightgreen)](https://zgca-forge.github.io/Elevator/)
@@ -27,21 +27,7 @@ Elevator Saga is a Python implementation of an elevator [simulation game](https:
### Basic Installation ### Basic Installation
```bash ```bash
pip install elevatorpy pip install elevator-py
```
### With Development Dependencies
```bash
pip install elevatorpy[dev]
```
### From Source
```bash
git clone https://github.com/ZGCA-Forge/Elevator.git
cd Elevator
pip install -e .[dev]
``` ```
## Quick Start ## Quick Start

View File

@@ -343,25 +343,6 @@ Benefits of Proxy Architecture
5. **Separation of Concerns**: State management handled by proxies, logic in controller 5. **Separation of Concerns**: State management handled by proxies, logic in controller
6. **Testability**: Can mock API client for unit tests 6. **Testability**: Can mock API client for unit tests
Performance Considerations
--------------------------
Each attribute access triggers an API call. For better performance:
.. code-block:: python
# ❌ Inefficient - multiple API calls
if elevator.current_floor < elevator.target_floor:
diff = elevator.target_floor - elevator.current_floor
# ✅ Better - store references
current = elevator.current_floor
target = elevator.target_floor
if current < target:
diff = target - current
However, the API client implements **caching within a single tick**, so multiple accesses during event processing are efficient.
Next Steps Next Steps
---------- ----------

View File

@@ -17,9 +17,9 @@ Architecture Overview
│ api_client │ │ │ │ api_client │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │ │
│ GET /api/state │ │ GET /api/state
│ POST /api/step │ │ POST /api/step
│ POST /api/elevators/:id/go_to_floor │ │ POST /api/elevators/:id/go_to_floor
│ │ │ │
└───────────────────────────────────────┘ └───────────────────────────────────────┘
@@ -394,37 +394,37 @@ Typical communication sequence during one tick:
.. code-block:: text .. code-block:: text
Client Server Client Server
│ │
│ 1. GET /api/state │ │ 1. GET /api/state
├────────────────────────────────────►│ ├────────────────────────────────────►│
│ ◄── SimulationState (cached) │ │ ◄── SimulationState (cached)
│ │
│ 2. Analyze state, make decisions │ │ 2. Analyze state, make decisions
│ │
│ 3. POST /api/elevators/0/go_to_floor │ 3. POST /api/elevators/0/go_to_floor│
├────────────────────────────────────►│ ├────────────────────────────────────►│
│ ◄── {"success": true} │ │ ◄── {"success": true}
│ │
│ 4. GET /api/state (from cache) │ │ 4. GET /api/state (from cache)
│ No HTTP request! │ │ No HTTP request!
│ │
│ 5. POST /api/step │ │ 5. POST /api/step
├────────────────────────────────────►│ ├────────────────────────────────────►│
│ Server processes tick │ │ Server processes tick
│ - Moves elevators │ │ - Moves elevators
│ - Boards/alights passengers │ │ - Boards/alights passengers
│ - Generates events │ │ - Generates events
│ ◄── {tick: 43, events: [...]} │ │ ◄── {tick: 43, events: [...]}
│ │
│ 6. Process events │ │ 6. Process events
│ Cache invalidated │ │ Cache invalidated
│ │
│ 7. GET /api/state (fetches fresh) │ │ 7. GET /api/state (fetches fresh)
├────────────────────────────────────►│ ├────────────────────────────────────►│
│ ◄── SimulationState │ │ ◄── SimulationState
│ │
└─────────────────────────────────────┘ └─────────────────────────────────────
Error Handling Error Handling
-------------- --------------
@@ -476,23 +476,6 @@ The simulator uses a lock to ensure thread-safe access:
This allows Flask to handle concurrent requests safely. This allows Flask to handle concurrent requests safely.
Performance Considerations
--------------------------
**Minimize HTTP Calls**:
.. code-block:: python
# ❌ Bad - 3 HTTP calls
for i in range(3):
state = api_client.get_state()
print(state.tick)
# ✅ Good - 1 HTTP call (cached)
state = api_client.get_state()
for i in range(3):
print(state.tick)
**Batch Commands**: **Batch Commands**:
.. code-block:: python .. code-block:: python

View File

@@ -8,21 +8,21 @@ Simulation Overview
.. code-block:: text .. code-block:: text
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────
│ Simulation Loop │ │ Simulation Loop │
│ │ │ │
│ Tick N │ │ Tick N │
│ 1. Update elevator status (START_UP → CONSTANT_SPEED)│ │ 1. Update elevator status (START_UP → CONSTANT_SPEED)
│ 2. Process arrivals (new passengers) │ │ 2. Process arrivals (new passengers) │
│ 3. Move elevators (physics simulation) │ │ 3. Move elevators (physics simulation) │
│ 4. Process stops (boarding/alighting) │ │ 4. Process stops (boarding/alighting) │
│ 5. Generate events │ │ 5. Generate events │
│ │ │ │
│ Events sent to client → Client processes → Commands │ │ Events sent to client → Client processes → Commands
│ │ │ │
│ Tick N+1 │ │ Tick N+1 │
│ (repeat...) │ │ (repeat...) │
└─────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────
Tick-Based Execution Tick-Based Execution
-------------------- --------------------
@@ -463,27 +463,6 @@ Here's what happens in a typical tick:
Key Timing Concepts Key Timing Concepts
------------------- -------------------
Command vs. Execution
~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
# Tick 42: Controller sends command
elevator.go_to_floor(5, immediate=False)
# ← Command queued in elevator.next_target_floor
# Tick 43: Server processes
# ← _update_elevator_status() assigns target
# ← Elevator starts moving
# Tick 44-46: Elevator in motion
# ← Events: PASSING_FLOOR
# Tick 47: Elevator arrives
# ← Event: STOPPED_AT_FLOOR
There's a **one-tick delay** between command and execution (unless ``immediate=True``).
Immediate vs. Queued Immediate vs. Queued
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
@@ -531,47 +510,6 @@ Key metrics:
- **System time**: ``dropoff_tick - arrive_tick`` (total time in system) - **System time**: ``dropoff_tick - arrive_tick`` (total time in system)
- **P95**: 95th percentile (worst-case for most passengers) - **P95**: 95th percentile (worst-case for most passengers)
Best Practices
--------------
1. **React to Events**: Don't poll state - implement event handlers
2. **Use Queued Commands**: Default ``immediate=False`` is safer
3. **Track Passengers**: Monitor ``on_passenger_call`` to know demand
4. **Optimize for Wait Time**: Reduce time between arrival and pickup
5. **Consider Load**: Check ``elevator.is_full`` before dispatching
6. **Handle Idle**: Always give idle elevators something to do (even if it's "go to floor 0")
Example: Efficient Dispatch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
def on_passenger_call(self, passenger: ProxyPassenger, floor: ProxyFloor, direction: str) -> None:
"""Dispatch nearest suitable elevator"""
best_elevator = None
best_cost = float('inf')
for elevator in self.elevators:
# Skip if full
if elevator.is_full:
continue
# Calculate cost (distance + current load)
distance = abs(elevator.current_floor - floor.floor)
load_penalty = elevator.load_factor * 10
cost = distance + load_penalty
# Check if going in right direction
if elevator.target_floor_direction.value == direction:
cost *= 0.5 # Prefer elevators already going that way
if cost < best_cost:
best_cost = cost
best_elevator = elevator
if best_elevator:
best_elevator.go_to_floor(floor.floor)
Summary Summary
------- -------

View File

@@ -1,12 +1,12 @@
Welcome to Elevator Saga's Documentation! Welcome to Elevator Saga's Documentation!
========================================== ==========================================
.. image:: https://badge.fury.io/py/elevatorpy.svg .. image:: https://badge.fury.io/py/elevator-py.svg
:target: https://badge.fury.io/py/elevatorpy :target: https://badge.fury.io/py/elevator-py
:alt: PyPI version :alt: PyPI version
.. image:: https://img.shields.io/pypi/pyversions/elevatorpy.svg .. image:: https://img.shields.io/pypi/pyversions/elevator-py.svg
:target: https://pypi.org/project/elevatorpy/ :target: https://pypi.org/project/elevator-py/
:alt: Python versions :alt: Python versions
.. image:: https://github.com/ZGCA-Forge/Elevator/actions/workflows/ci.yml/badge.svg .. image:: https://github.com/ZGCA-Forge/Elevator/actions/workflows/ci.yml/badge.svg
@@ -40,23 +40,7 @@ Basic Installation
.. code-block:: bash .. code-block:: bash
pip install elevatorpy pip install elevator-py
With Development Dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
pip install elevatorpy[dev]
From Source
~~~~~~~~~~~
.. code-block:: bash
git clone https://github.com/ZGCA-Forge/Elevator.git
cd Elevator
pip install -e .[dev]
Quick Start Quick Start
----------- -----------

View File

@@ -6,5 +6,5 @@ A Python implementation of the Elevator Saga game with event-driven architecture
realistic elevator dispatch algorithm development and testing. realistic elevator dispatch algorithm development and testing.
""" """
__version__ = "0.0.2" __version__ = "0.0.4"
__author__ = "ZGCA Team" __author__ = "ZGCA Team"

View File

@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
name = "elevatorpy" name = "elevator-py"
dynamic = ["version"] dynamic = ["version"]
description = "Python implementation of Elevator Saga game with event system" description = "Python implementation of Elevator Saga game with event system"
readme = "README.md" readme = "README.md"