{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# 2차시 — 위성 텔레메트리 분석\n",
        "\n",
        "**우송고 위성×AI · 3시간 · Lab A + Lab B**\n",
        "\n",
        "---\n",
        "\n",
        "## 오늘 할 일\n",
        "\n",
        "1. **CODE 1** — 텔레메트리 csv 불러오기 + 통계 요약 (pandas)\n",
        "2. **CODE 2** — 시간축 변환 + 한 채널 그래프 (matplotlib)\n",
        "3. **CODE 3** — 4 채널 한 번에 비교 (subplots)\n",
        "4. **CODE 4** — Gemini 와 상관 분석\n",
        "5. **CHALLENGE** — 3-tier\n",
        "\n",
        "## Run All 먼저\n",
        "\n",
        "메뉴 → 런타임 → 모두 실행 (Ctrl/Cmd + F9). 결과부터 보고, 셀별 *왜* 는 그 다음에.\n",
        "\n",
        "## 🚨 자주 막히는 곳\n",
        "\n",
        "| 증상 | 해결 |\n",
        "|---|---|\n",
        "| `FileNotFoundError: telemetry.csv` | 아래 *데이터 생성* 셀 먼저 실행 |\n",
        "| 한글 깨짐 | NanumGothic 셀 다시 실행 |\n",
        "| 그래프 안 보임 | 위 import 셀 다시 실행 |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 0. 환경 셋업 + 데이터 생성\n",
        "\n",
        "위성 텔레메트리는 보통 csv 파일로 받습니다. 여기서는 *진짜 위성 신호와 비슷한* 합성 데이터를 만들어 `telemetry.csv` 로 저장합니다. (실제 수업에서는 KARI·NASA 공개 데이터를 받아 쓸 수도 있어요.)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 한글 폰트\n",
        "!apt-get -qq install fonts-nanum > /dev/null\n",
        "import matplotlib.font_manager as fm\n",
        "fm.fontManager.addfont('/usr/share/fonts/truetype/nanum/NanumGothic.ttf')\n",
        "\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "plt.rcParams['font.family'] = 'NanumGothic'\n",
        "plt.rcParams['axes.unicode_minus'] = False\n",
        "\n",
        "# --- 위성 텔레메트리 합성 (1000초) ---\n",
        "np.random.seed(42)\n",
        "n = 1000\n",
        "t = np.arange(n)\n",
        "\n",
        "# 온도: 낮/밤 주기 (궤도 1바퀴 ~ 90분) + 노이즈\n",
        "temp = 20 + 80 * np.sin(t / 90) + np.random.normal(0, 5, n)\n",
        "# 배터리: 햇빛(온도 높을 때) 충전, 그늘에서 방전 → 온도와 양의 관계\n",
        "battery = 70 + 0.18 * (temp - 20) + np.random.normal(0, 3, n)\n",
        "battery = np.clip(battery, 0, 100)\n",
        "# 습도: 천천히 변동\n",
        "humidity = 45 + 10 * np.sin(t / 200 + 1) + np.random.normal(0, 2, n)\n",
        "# 통신: 지상국 지나갈 때만 강함 (주기적 봉우리)\n",
        "signal = -90 + 30 * np.clip(np.sin(t / 70), 0, 1) + np.random.normal(0, 3, n)\n",
        "\n",
        "time = pd.date_range('2026-03-01 00:00:00', periods=n, freq='s')\n",
        "df_gen = pd.DataFrame({\n",
        "    'time': time,\n",
        "    'temp': temp.round(1),\n",
        "    'humidity': humidity.round(1),\n",
        "    'battery': battery.round(1),\n",
        "    'signal': signal.round(1),\n",
        "})\n",
        "df_gen.to_csv('telemetry.csv', index=False)\n",
        "print('telemetry.csv 생성 완료 —', len(df_gen), '행')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — `telemetry.csv 생성 완료 — 1000 행`\n",
        "\n",
        "→ 이제 이 파일을 *불러오는 것부터* 진짜 분석 시작입니다. (실무에서는 이 csv 를 위성 관제소에서 받습니다.)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## CODE 1 — 표로 불러오기 (셀 1-6)\n",
        "\n",
        "**핵심**: pandas 로 csv 를 불러오면 *엑셀 같은 표* 가 됩니다. 이걸 데이터프레임(DataFrame)이라고 해요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# csv 불러오기\n",
        "df = pd.read_csv('telemetry.csv')\n",
        "\n",
        "print('모양 (행, 열):', df.shape)\n",
        "df.head()   # 위 5줄 미리보기"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — `(1000, 5)`, 그리고 time/temp/humidity/battery/signal 5개 열의 위 5줄.\n",
        "\n",
        "→ `.shape` 은 (행 수, 열 수). 1000초 × 5개 열."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 4 채널 통계 한 번에\n",
        "df.describe()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — temp/humidity/battery/signal 각각의 평균(mean), 최소(min), 최대(max), 표준편차(std) 등.\n",
        "> - temp 평균 약 27℃, 최대 110℃, 최소 -70℃ (궤도 낮/밤 차이가 큼)\n",
        "> - battery 평균 71% 근처\n",
        "\n",
        "→ `.describe()` 하나로 *수천 개 숫자를 한 표로 요약*. 이게 pandas 의 힘."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## CODE 2 — 시간축 + 한 채널 그래프 (셀 7-12)\n",
        "\n",
        "**핵심**: 시간에 따라 값이 어떻게 변하는지 = *시계열 그래프*."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# time 열을 진짜 시간(datetime)으로 변환\n",
        "df['time'] = pd.to_datetime(df['time'])\n",
        "print(df['time'].dtype)   # datetime64[ns]\n",
        "print('시작:', df['time'].iloc[0])\n",
        "print('끝  :', df['time'].iloc[-1])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 온도 채널 그래프\n",
        "plt.figure(figsize=(12, 4))\n",
        "plt.plot(df['time'], df['temp'], color='red', linewidth=1)\n",
        "plt.title('위성 온도 변화 (1000초)', fontsize=15, fontweight='bold')\n",
        "plt.xlabel('time')\n",
        "plt.ylabel('temp (℃)')\n",
        "plt.grid(alpha=0.3)\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — 온도가 *주기적으로 오르내리는* 물결 모양.\n",
        "\n",
        "→ 왜 주기적일까요? 위성이 지구를 한 바퀴 돌면서 *햇빛 → 그늘 → 햇빛* 을 반복하기 때문. 햇빛 받으면 뜨겁고, 지구 그늘(식)에 들어가면 차가워집니다."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## CODE 3 — 4 채널 한 번에 (셀 13-18)\n",
        "\n",
        "**핵심**: 한 채널만 보면 모릅니다. *여러 채널을 같이 봐야* 위성 상태를 이해할 수 있어요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 4 채널을 2x2 격자로 한 번에\n",
        "fig, ax = plt.subplots(2, 2, figsize=(13, 7))\n",
        "channels = ['temp', 'humidity', 'battery', 'signal']\n",
        "colors = ['red', 'blue', 'green', 'purple']\n",
        "titles = ['온도 (℃)', '습도 (%)', '배터리 (%)', '통신 (dB)']\n",
        "\n",
        "for a, ch, c, ti in zip(ax.flat, channels, colors, titles):\n",
        "    a.plot(df['time'], df[ch], color=c, linewidth=1)\n",
        "    a.set_title(ti, fontsize=13, fontweight='bold')\n",
        "    a.grid(alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — 4개 그래프가 2×2 로 배치.\n",
        "> - 온도: 큰 물결 (낮/밤)\n",
        "> - 배터리: 온도와 *비슷한* 물결 (햇빛 충전)\n",
        "> - 습도: 천천히 변동\n",
        "> - 통신: 봉우리가 반복 (지상국 지날 때만 강함)\n",
        "\n",
        "→ **관찰**: 온도가 오를 때 배터리도 오르는 게 보이나요? 이게 다음 단계의 핵심입니다."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 🤖 GEMINI 와 페어 작업 — 상관 분석\n",
        "\n",
        "**[gemini.google.com](https://gemini.google.com) 에 아래 프롬프트를 그대로 복사해 붙여넣으세요**:\n",
        "\n",
        "```\n",
        "pandas 데이터프레임 df 에 temp, humidity, battery, signal 4개 열이 있어.\n",
        "이 네 채널 사이의 상관관계(correlation)를 계산하고,\n",
        "matplotlib 으로 heatmap 처럼 색으로 보여주는 코드를 짜줘.\n",
        "어떤 두 채널이 가장 관련이 깊은지도 한 줄로 설명해줘.\n",
        "한국어로 답해줘.\n",
        "```\n",
        "\n",
        "→ Gemini 가 준 코드를 아래 빈 셀에 붙여넣고 실행하세요."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 여기에 Gemini 가 준 코드 붙여넣기.\n",
        "# 막히면 아래 참고 답과 비교.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 📌 참고 답 (Gemini 답과 비교용)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 4 채널 상관계수 + heatmap\n",
        "cols = ['temp', 'humidity', 'battery', 'signal']\n",
        "corr = df[cols].corr()\n",
        "print(corr.round(2))\n",
        "\n",
        "plt.figure(figsize=(6, 5))\n",
        "plt.imshow(corr, cmap='coolwarm', vmin=-1, vmax=1)\n",
        "plt.colorbar(label='상관계수')\n",
        "plt.xticks(range(len(cols)), cols, rotation=45)\n",
        "plt.yticks(range(len(cols)), cols)\n",
        "# 각 칸에 숫자 표시\n",
        "for i in range(len(cols)):\n",
        "    for j in range(len(cols)):\n",
        "        plt.text(j, i, f'{corr.iloc[i,j]:.2f}', ha='center', va='center', fontweight='bold')\n",
        "plt.title('4 채널 상관계수', fontsize=14, fontweight='bold')\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "> 💡 **예상 결과** — temp 와 battery 사이 상관계수가 *매우 높게 (0.9 이상)* 나옵니다.\n",
        "> - 상관계수 1 = 완전히 같이 움직임\n",
        "> - 0 = 관계 없음\n",
        "> - -1 = 반대로 움직임\n",
        "\n",
        "> ⚠️ **중요 — 상관 ≠ 인과**\n",
        "> temp 와 battery 가 같이 움직인다고 *온도가 배터리를 올린다* 고 단정할 수 없어요. 사실은 *햇빛* 이라는 공통 원인이 둘 다 올린 겁니다. AI 가 \"관련 있다\" 고 해도 *왜* 인지는 사람이 판단해야 합니다."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## ✓ 체크포인트 — LEVEL 1\n",
        "\n",
        "- [ ] `telemetry.csv` 불러왔다 (`df.shape == (1000, 5)`)\n",
        "- [ ] `describe()` 로 통계를 봤다\n",
        "- [ ] 온도 그래프를 그렸다\n",
        "- [ ] 4 채널을 한 번에 비교했다\n",
        "\n",
        "→ 다 ✓ 면 CHALLENGE 로."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 🎯 CHALLENGE\n",
        "\n",
        "### LEVEL 1 (최소) — 4 채널 관찰\n",
        "\n",
        "아래 markdown 셀에 각 채널이 *어떤 패턴* 인지 한 줄씩 적어보세요."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**내 관찰**:\n",
        "- 온도: ___\n",
        "- 습도: ___\n",
        "- 배터리: ___\n",
        "- 통신: ___"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### LEVEL 2 (권장) — 상관 분석 해석\n",
        "\n",
        "위 heatmap 에서 가장 관련 깊은 두 채널을 찾고, *왜 그럴지* 추측해서 적어보세요.\n",
        "\n",
        "**🤖 Gemini 에게 물어봐**: \"온도와 배터리의 상관계수가 0.96 으로 매우 높게 나왔어. 위성에서 이 둘이 왜 관련 있을지 이유를 3가지 알려줘.\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**가장 관련 깊은 두 채널**: ___ 와 ___\n",
        "\n",
        "**내가 생각하는 이유**: ___"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### LEVEL 3 (도전) — 자기 질문\n",
        "\n",
        "본인이 궁금한 질문을 하나 정하고, Gemini 와 함께 코드로 답을 찾아보세요.\n",
        "\n",
        "질문 예시:\n",
        "- 온도가 가장 높은 시간대는 언제인가?\n",
        "- 배터리가 50% 아래로 떨어진 적이 있는가?\n",
        "- 통신이 강한 구간은 전체의 몇 % 인가?\n",
        "\n",
        "**🤖 Gemini 프롬프트 예시**: \"df 에서 temp 가 가장 높은 행의 time 과 temp 값을 출력하는 코드를 짜줘.\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 내 질문에 답하는 코드 (Gemini 답 또는 직접 작성)\n",
        "# 예시: 온도가 가장 높은 순간\n",
        "hottest = df.loc[df['temp'].idxmax()]\n",
        "print('가장 더운 순간:')\n",
        "print('  시각:', hottest['time'])\n",
        "print('  온도:', hottest['temp'], '℃')\n",
        "print('  그때 배터리:', hottest['battery'], '%')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**내 질문**: ___\n",
        "\n",
        "**찾은 답**: ___"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 🚨 추가 실습 60분 — 위성 관제 알림 시스템 만들기\n",
        "\n",
        "여기부터는 **따라하기가 아니라 관제 기준을 직접 설계**하는 미션입니다.\n",
        "\n",
        "상황: 여러분은 위성 관제센터 팀입니다. 위성에서 1초마다 들어오는 `temp`, `battery`, `signal` 값을 보고 **언제 위험 알림을 띄울지** 정해야 합니다.\n",
        "\n",
        "오늘의 산출물:\n",
        "1. 내가 정한 위험 기준 3개\n",
        "2. 위험 구간 그래프 1장\n",
        "3. 관제센터 브리핑 문장 3줄\n",
        "4. 기준을 바꾸면 결과가 어떻게 달라지는지 비교\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# MISSION 0 — 원본 데이터를 보존하고, 사고 상황을 복사본에 주입합니다.\n",
        "# 아래 숫자를 바꾸면 다른 사건을 만들 수 있습니다.\n",
        "\n",
        "mission = df.copy()\n",
        "\n",
        "# 사건 A: 과열 + 배터리 급락\n",
        "mission.loc[220:280, 'temp'] += 35\n",
        "mission.loc[220:280, 'battery'] -= 28\n",
        "\n",
        "# 사건 B: 지상국 연결 약화\n",
        "mission.loc[610:690, 'signal'] -= 25\n",
        "\n",
        "# 물리적으로 가능한 범위로 정리\n",
        "mission['battery'] = mission['battery'].clip(0, 100)\n",
        "\n",
        "print('mission 데이터 준비 완료:', mission.shape)\n",
        "print('원본 temp 최대:', df['temp'].max(), '→ mission temp 최대:', mission['temp'].max())\n",
        "print('원본 battery 최소:', df['battery'].min(), '→ mission battery 최소:', mission['battery'].min())\n",
        "print('원본 signal 최소:', df['signal'].min(), '→ mission signal 최소:', mission['signal'].min())\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### MISSION 1 — 위험 기준을 직접 정하기\n",
        "\n",
        "아래 세 숫자가 여러분 팀의 관제 기준입니다. 너무 엄격하면 알림이 너무 많이 뜨고, 너무 느슨하면 위험을 놓칩니다.\n",
        "\n",
        "먼저 기본값으로 실행한 뒤, 숫자를 바꿔보세요.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# TODO: 팀별로 이 기준을 바꿔보세요.\n",
        "TEMP_LIMIT = 105      # 이 온도보다 높으면 과열 의심\n",
        "BATTERY_LIMIT = 58    # 이 배터리보다 낮으면 전력 위험\n",
        "SIGNAL_LIMIT = -98    # 이 신호보다 낮으면 통신 위험\n",
        "\n",
        "mission['temp_alert'] = mission['temp'] > TEMP_LIMIT\n",
        "mission['battery_alert'] = mission['battery'] < BATTERY_LIMIT\n",
        "mission['signal_alert'] = mission['signal'] < SIGNAL_LIMIT\n",
        "\n",
        "mission['alert_count'] = mission[['temp_alert', 'battery_alert', 'signal_alert']].sum(axis=1)\n",
        "mission['status'] = np.select(\n",
        "    [mission['alert_count'] >= 2, mission['alert_count'] == 1],\n",
        "    ['CRITICAL', 'WATCH'],\n",
        "    default='NORMAL'\n",
        ")\n",
        "\n",
        "print(mission['status'].value_counts())\n",
        "mission[['time', 'temp', 'battery', 'signal', 'alert_count', 'status']].head()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### MISSION 2 — 위험 구간 찾기\n",
        "\n",
        "`CRITICAL`은 2개 이상 센서가 동시에 위험 기준을 넘은 순간입니다. 관제센터라면 이 구간을 먼저 확인해야 합니다.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "critical = mission[mission['status'] == 'CRITICAL']\n",
        "watch = mission[mission['status'] == 'WATCH']\n",
        "\n",
        "print('WATCH 초:', len(watch))\n",
        "print('CRITICAL 초:', len(critical))\n",
        "\n",
        "if len(critical) > 0:\n",
        "    print('첫 CRITICAL 시각:', critical['time'].iloc[0])\n",
        "    print('마지막 CRITICAL 시각:', critical['time'].iloc[-1])\n",
        "    print(critical[['time', 'temp', 'battery', 'signal', 'alert_count', 'status']].head(10).to_string(index=False))\n",
        "else:\n",
        "    print('CRITICAL 없음 — 기준이 너무 느슨한지 확인해보세요.')\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### MISSION 3 — 관제 그래프 만들기\n",
        "\n",
        "빨간 점은 `CRITICAL`, 주황 점은 `WATCH`입니다. 그래프를 보고 실제로 위험해 보이는지 판단하세요.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "fig, ax = plt.subplots(3, 1, figsize=(14, 9), sharex=True)\n",
        "plot_items = [\n",
        "    ('temp', '온도 ℃', 'red', TEMP_LIMIT),\n",
        "    ('battery', '배터리 %', 'green', BATTERY_LIMIT),\n",
        "    ('signal', '통신 dB', 'purple', SIGNAL_LIMIT),\n",
        "]\n",
        "\n",
        "for a, (ch, label, color, limit) in zip(ax, plot_items):\n",
        "    a.plot(mission['time'], mission[ch], color=color, linewidth=1, alpha=0.8)\n",
        "    if ch == 'temp':\n",
        "        a.axhline(limit, color='black', linestyle='--', linewidth=1, label='위험 기준')\n",
        "    else:\n",
        "        a.axhline(limit, color='black', linestyle='--', linewidth=1, label='위험 기준')\n",
        "    a.scatter(mission.loc[mission['status']=='WATCH', 'time'],\n",
        "              mission.loc[mission['status']=='WATCH', ch],\n",
        "              color='orange', s=10, label='WATCH')\n",
        "    a.scatter(mission.loc[mission['status']=='CRITICAL', 'time'],\n",
        "              mission.loc[mission['status']=='CRITICAL', ch],\n",
        "              color='black', s=14, label='CRITICAL')\n",
        "    a.set_ylabel(label)\n",
        "    a.grid(alpha=0.3)\n",
        "    a.legend(loc='upper right')\n",
        "\n",
        "plt.suptitle('위성 관제 알림 대시보드', fontsize=16, fontweight='bold')\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### MISSION 4 — 기준 바꾸기 실험\n",
        "\n",
        "아래 질문에 답할 때까지 `TEMP_LIMIT`, `BATTERY_LIMIT`, `SIGNAL_LIMIT`를 바꿔보세요.\n",
        "\n",
        "- 알림이 너무 많이 뜨나요?\n",
        "- 진짜 위험 구간을 놓치지는 않나요?\n",
        "- 여러분 팀 기준은 보수적인가요, 공격적인가요?\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 팀 기준 요약표\n",
        "summary = {\n",
        "    'TEMP_LIMIT': TEMP_LIMIT,\n",
        "    'BATTERY_LIMIT': BATTERY_LIMIT,\n",
        "    'SIGNAL_LIMIT': SIGNAL_LIMIT,\n",
        "    'NORMAL_seconds': int((mission['status'] == 'NORMAL').sum()),\n",
        "    'WATCH_seconds': int((mission['status'] == 'WATCH').sum()),\n",
        "    'CRITICAL_seconds': int((mission['status'] == 'CRITICAL').sum()),\n",
        "    'max_temp': float(mission['temp'].max()),\n",
        "    'min_battery': float(mission['battery'].min()),\n",
        "    'min_signal': float(mission['signal'].min()),\n",
        "}\n",
        "\n",
        "for k, v in summary.items():\n",
        "    print(f'{k}: {v}')\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### MISSION 5 — Gemini에게 관제 규칙 리뷰 받기\n",
        "\n",
        "Gemini에 아래 내용을 복사해서 물어보세요.\n",
        "\n",
        "```text\n",
        "나는 위성 관제 알림 기준을 이렇게 정했어.\n",
        "TEMP_LIMIT = ___\n",
        "BATTERY_LIMIT = ___\n",
        "SIGNAL_LIMIT = ___\n",
        "NORMAL 초 = ___, WATCH 초 = ___, CRITICAL 초 = ___\n",
        "최대 온도 = ___, 최소 배터리 = ___, 최소 신호 = ___\n",
        "\n",
        "이 기준이 너무 엄격한지/느슨한지 평가해줘.\n",
        "그리고 고등학생 수준에서 개선 아이디어 2개만 제안해줘.\n",
        "```\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 최종 기록 — 관제센터 브리핑\n",
        "\n",
        "아래 빈칸을 채우세요. 발표는 30초면 됩니다.\n",
        "\n",
        "- 우리 팀 위험 기준: 온도 > ___, 배터리 < ___, 신호 < ___\n",
        "- CRITICAL이 발생한 시간: ___초\n",
        "- 가장 위험했던 순간: ___\n",
        "- 우리가 내릴 관제 판단: ___\n",
        "- 기준을 더 좋게 만들려면: ___\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## 📝 발표 준비 (B4)\n",
        "\n",
        "페어로 1분씩:\n",
        "1. 4 채널 중 가장 흥미로운 패턴은?\n",
        "2. 가장 관련 깊은 두 채널과 그 이유는?\n",
        "3. 내 질문(LEVEL 3)과 찾은 답은?\n",
        "4. 어디서 막혔나?\n",
        "\n",
        "### 노트북 저장\n",
        "파일 → 드라이브에 사본 저장 → `02_본인이름.ipynb`\n",
        "\n",
        "---\n",
        "\n",
        "## 🎉 2차시 완료\n",
        "\n",
        "- pandas 로 표 다루기 (read_csv, describe)\n",
        "- 시계열 그래프 (matplotlib)\n",
        "- 4 채널 동시 비교 (subplots)\n",
        "- 상관 분석 + 상관 ≠ 인과\n",
        "\n",
        "**다음 주 — C3: 위성 이상 진단 (scikit-learn 이상 탐지)**\n",
        "\n",
        "🛰️ 수고하셨습니다."
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.10"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
