# Part 5: AI 핵심 라이브러리 실습 (Numpy, Pandas, Matplotlib)

# 이 스크립트를 실행하기 전에 라이브러리를 설치해야 합니다.
# pip install numpy pandas matplotlib

import os

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# --- Numpy (Numerical Python) ---
print("--- Numpy 실습 ---")

# Numpy 배열 생성
arr = np.array([1, 2, 3, 4, 5])
print(f"1차원 배열: {arr}")

arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(f"2차원 배열:\n{arr2d}")

# 배열의 형태, 차원, 타입 확인
print(f"형태(shape): {arr2d.shape}")
print(f"차원(ndim): {arr2d.ndim}")
print(f"타입(dtype): {arr2d.dtype}")

# Numpy 연산 (브로드캐스팅)
arr_a = np.array([1, 2, 3])
arr_b = np.array([4, 5, 6])
print(f"배열 A: {arr_a}")
print(f"배열 B: {arr_b}")
print(f"A + B = {arr_a + arr_b}")
print(f"A * 2 = {arr_a * 2}")

# 다양한 배열 생성
zeros_arr = np.zeros((2, 3))
print(f"0으로 채워진 배열:\n{zeros_arr}")
ones_arr = np.ones((3, 2))
print(f"1로 채워진 배열:\n{ones_arr}")
range_arr = np.arange(0, 10, 2)  # 0부터 10 전까지 2의 간격으로
print(f"arange(0, 10, 2): {range_arr}")
print("-" * 30)


# --- Pandas (Python Data Analysis Library) ---
print("\n--- Pandas 실습 ---")

# Pandas Series 생성 (1차원 데이터)
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(f"Pandas Series:\n{s}")

# Pandas DataFrame 생성 (2차원 데이터)
data = {
    "이름": ["Alice", "Bob", "Charlie", "David"],
    "나이": [25, 30, 35, 28],
    "도시": ["서울", "부산", "서울", "대전"],
}
df = pd.DataFrame(data)

print(f"\nPandas DataFrame:\n{df}")

# 데이터 확인
print("\nDataFrame 정보 (info):")
df.info()

print(f"\n상위 2개 데이터 (head):\n{df.head(2)}")
print(f"\n기술 통계 (describe):\n{df.describe()}")

# 데이터 선택
print(f"\n'이름' 컬럼 선택:\n{df['이름']}")
print(f"\n0번, 1번 행 선택 (iloc):\n{df.iloc[0:2]}")
print(f"\n'나이'가 30 이상인 데이터 필터링:\n{df[df['나이'] >= 30]}")

# 데이터 추가 및 수정
df["월급"] = [300, 400, 500, 350]
print(f"\n'월급' 컬럼 추가 후:\n{df}")
print("-" * 30)


# --- Matplotlib (Data Visualization Library) ---
print("\n--- Matplotlib 실습 ---")

# 저장할 디렉터리 생성
output_dir = "plot_outputs"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
print(f"그래프는 '{output_dir}' 폴더에 저장됩니다.")

# 1. 라인 플롯 (Line Plot)
x = np.arange(0, 10, 0.1)
y = np.sin(x)

plt.figure(figsize=(10, 5))
plt.plot(x, y, label="sin(x)")
plt.title("Sine Wave")
plt.xlabel("x-axis")
plt.ylabel("y-axis")
plt.grid(True)
plt.legend()

# 그래프를 파일로 저장
line_plot_path = os.path.join(output_dir, "line_plot.png")
plt.savefig(line_plot_path)
print(f"라인 플롯 저장 완료: {line_plot_path}")
plt.close()  # 플롯 창을 닫아 다음 플롯에 영향이 없도록 함

# 2. 바 차트 (Bar Chart)
cities = df["도시"].value_counts()

plt.figure(figsize=(8, 6))
cities.plot(kind="bar", color=["skyblue", "salmon", "lightgreen"])
plt.title("City Distribution")
plt.xlabel("City")
plt.ylabel("Number of People")
plt.xticks(rotation=0)  # x축 레이블 회전 방지

bar_chart_path = os.path.join(output_dir, "bar_chart.png")
plt.savefig(bar_chart_path)
print(f"바 차트 저장 완료: {bar_chart_path}")
plt.close()

# 3. 스캐터 플롯 (Scatter Plot)
x_rand = np.random.rand(50)
y_rand = np.random.rand(50)
colors = np.random.rand(50)
area = (30 * np.random.rand(50)) ** 2

plt.figure(figsize=(10, 6))
plt.scatter(x_rand, y_rand, s=area, c=colors, alpha=0.5)
plt.title("Scatter Plot")
plt.xlabel("Random X")
plt.ylabel("Random Y")

scatter_plot_path = os.path.join(output_dir, "scatter_plot.png")
plt.savefig(scatter_plot_path)
print(f"스캐터 플롯 저장 완료: {scatter_plot_path}")
plt.close()

print("-" * 30)
