Rohannk's picture
Upload 5 files
2418f42 verified
Raw
History Blame Contribute Delete
3.07 kB
from fastapi import FastAPI
from pydantic import BaseModel
import random
app = FastAPI()
# 1. Typed Models for Actions
class Action(BaseModel):
fan_change_rack1: int # -1 (decrease), 0 (keep), 1 (increase)
fan_change_rack2: int
fan_change_rack3: int
# 2. State Management
class State:
def __init__(self):
self.rack_temps = [30.0, 32.0, 28.0]
self.fan_speeds = [2, 2, 2] # Scale 1-5
self.power_usage = 300
self.step_count = 0
def reset(self):
# Start with random high temperatures
self.rack_temps = [random.uniform(28.0, 35.0) for _ in range(3)]
self.fan_speeds = [2, 2, 2]
self.power_usage = sum(self.fan_speeds) * 50
self.step_count = 0
current_state = State()
# 3. Required Endpoints
@app.get("/")
def read_root():
return {"status": "ok"}
@app.post("/reset")
def reset():
current_state.reset()
return get_state()
@app.get("/state")
def get_state():
return {
"rack_temps": [round(t, 2) for t in current_state.rack_temps],
"fan_speeds": current_state.fan_speeds,
"power_usage": current_state.power_usage,
"step_count": current_state.step_count
}
# 4. Step Logic and Graders
def calculate_score(temp):
"""Partial progress signal: 1.0 if perfect (<25C), drops to 0.0 if too hot."""
if temp <= 25.0: return 1.0
if temp >= 35.0: return 0.0
return round(1.0 - ((temp - 25.0) / 10.0), 2)
@app.post("/step")
def step(action: Action):
current_state.step_count += 1
# Apply Actions: Update fan speeds (clamp between 1 and 5)
current_state.fan_speeds[0] = max(1, min(5, current_state.fan_speeds[0] + action.fan_change_rack1))
current_state.fan_speeds[1] = max(1, min(5, current_state.fan_speeds[1] + action.fan_change_rack2))
current_state.fan_speeds[2] = max(1, min(5, current_state.fan_speeds[2] + action.fan_change_rack3))
# Simple Physics: Heat naturally increases, fans decrease it
for i in range(3):
base_heat = 1.5
cooling_power = current_state.fan_speeds[i] * 0.8
current_state.rack_temps[i] += (base_heat - cooling_power)
# Calculate total power
current_state.power_usage = sum(current_state.fan_speeds) * 50
# GRADERS (0.0 to 1.0)
# Task 1 (Easy): Cool down Rack 1
score_easy = calculate_score(current_state.rack_temps[0])
# Task 2 (Medium): Cool down all racks
score_medium = sum([calculate_score(t) for t in current_state.rack_temps]) / 3.0
# Task 3 (Hard): Cool all racks AND keep power under 500W
power_penalty = 1.0 if current_state.power_usage <= 500 else 0.5
score_hard = round(score_medium * power_penalty, 2)
return {
"state": get_state(),
"scores": {
"easy": score_easy,
"medium": score_medium,
"hard": score_hard
},
"done": current_state.step_count >= 15 # End episode after 15 steps
}