"""OSN AI 2025 exhibition final: EDA of cinema ticket sales (Indonesia). Answers to Soal 1-5 + bonus, and the figure.
The dataset is the literal list given in the notebook (60 screenings), copied verbatim below."""
import pandas as pd
import matplotlib; matplotlib.use("Agg"); import matplotlib.pyplot as plt
data = [
{'judul_film': 'Train to Busan', 'genre': 'Drama', 'harga_tiket': 70000, 'jumlah_tiket': 121, 'tanggal': '2025-06-12', 'kota': 'Makassar', 'jam_tayang': '13:00', 'studio': 'C'},
{'judul_film': 'The Avengers: Endgame', 'genre': 'Drama', 'harga_tiket': 55000, 'jumlah_tiket': 130, 'tanggal': '2025-06-15', 'kota': 'yogyakarta', 'jam_tayang': '22:00', 'studio': 'C'},
{'judul_film': 'Spiderman: Homecoming', 'genre': 'Sci-Fi', 'harga_tiket': 70000, 'jumlah_tiket': 113, 'tanggal': '2025-06-12', 'kota': 'yogyakarta', 'jam_tayang': '16:00', 'studio': 'B'},
{'judul_film': 'Doctor Strange: Multiverse of Madness', 'genre': 'Animasi', 'harga_tiket': 50000, 'jumlah_tiket': 74, 'tanggal': '2025-06-09', 'kota': 'SBY', 'jam_tayang': '19:30', 'studio': 'C'},
{'judul_film': 'Frozen II', 'genre': 'Animasi', 'harga_tiket': 65000, 'jumlah_tiket': 132, 'tanggal': '2025-06-08', 'kota': 'MAKASSAR', 'jam_tayang': '18:00', 'studio': 'A'},
{'judul_film': 'Avengers: Infinity War', 'genre': 'Drama', 'harga_tiket': 75000, 'jumlah_tiket': 133, 'tanggal': '2025-06-01', 'kota': 'Jakarta', 'jam_tayang': '18:00', 'studio': 'D'},
{'judul_film': 'Train to Busan', 'genre': 'Komedi', 'harga_tiket': 55000, 'jumlah_tiket': 123, 'tanggal': '2025-06-01', 'kota': 'Bandung', 'jam_tayang': '19:30', 'studio': 'C'},
{'judul_film': 'Black Panther', 'genre': 'Action', 'harga_tiket': 55000, 'jumlah_tiket': 81, 'tanggal': '2025-06-04', 'kota': 'YOGYAKARTA', 'jam_tayang': '16:00', 'studio': 'C'},
{'judul_film': 'Captain America', 'genre': 'Komedi', 'harga_tiket': 80000, 'jumlah_tiket': 147, 'tanggal': '2025-06-09', 'kota': 'Surabaya', 'jam_tayang': '13:00', 'studio': 'D'},
{'judul_film': 'Avengers: Infinity War', 'genre': 'Sci-Fi', 'harga_tiket': 55000, 'jumlah_tiket': 150, 'tanggal': '2025-06-02', 'kota': 'jakarta', 'jam_tayang': '13:00', 'studio': 'C'},
{'judul_film': 'Inception', 'genre': 'Action', 'harga_tiket': 55000, 'jumlah_tiket': 130, 'tanggal': '2025-06-07', 'kota': 'Surabaya', 'jam_tayang': '14:30', 'studio': 'A'},
{'judul_film': 'Joker', 'genre': 'Animasi', 'harga_tiket': 75000, 'jumlah_tiket': 80, 'tanggal': '2025-06-14', 'kota': 'MEDAN', 'jam_tayang': '13:00', 'studio': 'A'},
{'judul_film': 'Iron Man', 'genre': 'Animasi', 'harga_tiket': 65000, 'jumlah_tiket': 67, 'tanggal': '2025-06-01', 'kota': 'makassar', 'jam_tayang': '18:00', 'studio': 'C'},
{'judul_film': 'Captain America', 'genre': 'Horor', 'harga_tiket': 80000, 'jumlah_tiket': 140, 'tanggal': '2025-06-15', 'kota': 'Semarang', 'jam_tayang': '20:00', 'studio': 'B'},
{'judul_film': 'Frozen II', 'genre': 'Sci-Fi', 'harga_tiket': 70000, 'jumlah_tiket': 65, 'tanggal': '2025-06-12', 'kota': 'JOGJA', 'jam_tayang': '20:00', 'studio': 'B'},
{'judul_film': 'Spiderman: No Way Home', 'genre': 'Komedi', 'harga_tiket': 80000, 'jumlah_tiket': 118, 'tanggal': '2025-06-12', 'kota': 'semarang', 'jam_tayang': '19:30', 'studio': 'D'},
{'judul_film': 'Captain America', 'genre': 'Drama', 'harga_tiket': 70000, 'jumlah_tiket': 131, 'tanggal': '2025-06-14', 'kota': 'JKT', 'jam_tayang': '16:00', 'studio': 'B'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Action', 'harga_tiket': 70000, 'jumlah_tiket': 103, 'tanggal': '2025-06-06', 'kota': 'Medan', 'jam_tayang': '14:30', 'studio': 'B'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Sci-Fi', 'harga_tiket': 75000, 'jumlah_tiket': 63, 'tanggal': '2025-06-10', 'kota': 'MEDAN', 'jam_tayang': '14:30', 'studio': 'B'},
{'judul_film': 'Doctor Strange: Multiverse of Madness', 'genre': 'Action', 'harga_tiket': 80000, 'jumlah_tiket': 66, 'tanggal': '2025-06-01', 'kota': 'MEDAN', 'jam_tayang': '19:30', 'studio': 'D'},
{'judul_film': 'Inception', 'genre': 'Action', 'harga_tiket': 60000, 'jumlah_tiket': 131, 'tanggal': '2025-06-08', 'kota': 'SURABAYA', 'jam_tayang': '13:00', 'studio': 'D'},
{'judul_film': 'Spiderman: No Way Home', 'genre': 'Sci-Fi', 'harga_tiket': 70000, 'jumlah_tiket': 66, 'tanggal': '2025-06-02', 'kota': 'Jakarta', 'jam_tayang': '19:30', 'studio': 'D'},
{'judul_film': 'Parasite', 'genre': 'Komedi', 'harga_tiket': 75000, 'jumlah_tiket': 85, 'tanggal': '2025-06-12', 'kota': 'SEMARANG', 'jam_tayang': '21:00', 'studio': 'D'},
{'judul_film': 'Frozen II', 'genre': 'Drama', 'harga_tiket': 75000, 'jumlah_tiket': 79, 'tanggal': '2025-06-11', 'kota': 'SURABAYA', 'jam_tayang': '20:00', 'studio': 'A'},
{'judul_film': 'Avenger Boy', 'genre': 'Komedi', 'harga_tiket': 55000, 'jumlah_tiket': 111, 'tanggal': '2025-06-08', 'kota': 'SMG', 'jam_tayang': '20:00', 'studio': 'A'},
{'judul_film': 'Black Panther', 'genre': 'Action', 'harga_tiket': 60000, 'jumlah_tiket': 105, 'tanggal': '2025-06-14', 'kota': 'SBY', 'jam_tayang': '18:00', 'studio': 'C'},
{'judul_film': 'Your Name', 'genre': 'Komedi', 'harga_tiket': 65000, 'jumlah_tiket': 77, 'tanggal': '2025-06-15', 'kota': 'SEMARANG', 'jam_tayang': '20:00', 'studio': 'B'},
{'judul_film': 'Spiderman: Far From Home', 'genre': 'Drama', 'harga_tiket': 65000, 'jumlah_tiket': 133, 'tanggal': '2025-06-06', 'kota': 'Yogyakarta', 'jam_tayang': '13:00', 'studio': 'B'},
{'judul_film': 'Spiderman: No Way Home', 'genre': 'Sci-Fi', 'harga_tiket': 80000, 'jumlah_tiket': 104, 'tanggal': '2025-06-13', 'kota': 'MAKASSAR', 'jam_tayang': '14:30', 'studio': 'A'},
{'judul_film': 'Laskar Pelangi', 'genre': 'Komedi', 'harga_tiket': 60000, 'jumlah_tiket': 139, 'tanggal': '2025-06-10', 'kota': 'SBY', 'jam_tayang': '19:30', 'studio': 'C'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Horor', 'harga_tiket': 80000, 'jumlah_tiket': 91, 'tanggal': '2025-06-15', 'kota': 'semarang', 'jam_tayang': '18:00', 'studio': 'A'},
{'judul_film': 'Inception', 'genre': 'Komedi', 'harga_tiket': 75000, 'jumlah_tiket': 78, 'tanggal': '2025-06-05', 'kota': 'MEDAN', 'jam_tayang': '22:00', 'studio': 'A'},
{'judul_film': 'Kimi no Na wa', 'genre': 'Komedi', 'harga_tiket': 80000, 'jumlah_tiket': 66, 'tanggal': '2025-06-04', 'kota': 'YOGYAKARTA', 'jam_tayang': '14:30', 'studio': 'D'},
{'judul_film': 'Frozen II', 'genre': 'Komedi', 'harga_tiket': 50000, 'jumlah_tiket': 61, 'tanggal': '2025-06-11', 'kota': 'Bandung', 'jam_tayang': '21:00', 'studio': 'C'},
{'judul_film': 'Avenger Boy', 'genre': 'Action', 'harga_tiket': 65000, 'jumlah_tiket': 85, 'tanggal': '2025-06-04', 'kota': 'makassar', 'jam_tayang': '19:30', 'studio': 'A'},
{'judul_film': 'Your Name', 'genre': 'Komedi', 'harga_tiket': 65000, 'jumlah_tiket': 135, 'tanggal': '2025-06-04', 'kota': 'JKT', 'jam_tayang': '20:00', 'studio': 'A'},
{'judul_film': 'The Avengers Assemble', 'genre': 'Horor', 'harga_tiket': 75000, 'jumlah_tiket': 132, 'tanggal': '2025-06-07', 'kota': 'Makassar', 'jam_tayang': '16:00', 'studio': 'A'},
{'judul_film': 'Parasite', 'genre': 'Horor', 'harga_tiket': 80000, 'jumlah_tiket': 74, 'tanggal': '2025-06-08', 'kota': 'MAKASSAR', 'jam_tayang': '21:00', 'studio': 'B'},
{'judul_film': 'The Batman', 'genre': 'Komedi', 'harga_tiket': 70000, 'jumlah_tiket': 62, 'tanggal': '2025-06-10', 'kota': 'MEDAN', 'jam_tayang': '13:00', 'studio': 'A'},
{'judul_film': 'Spiderman: Far From Home', 'genre': 'Animasi', 'harga_tiket': 60000, 'jumlah_tiket': 60, 'tanggal': '2025-06-08', 'kota': 'Jakarta', 'jam_tayang': '14:30', 'studio': 'B'},
{'judul_film': 'The Batman', 'genre': 'Animasi', 'harga_tiket': 75000, 'jumlah_tiket': 94, 'tanggal': '2025-06-02', 'kota': 'SMG', 'jam_tayang': '14:30', 'studio': 'C'},
{'judul_film': 'Captain America', 'genre': 'Action', 'harga_tiket': 60000, 'jumlah_tiket': 116, 'tanggal': '2025-06-12', 'kota': 'jakarta', 'jam_tayang': '19:30', 'studio': 'B'},
{'judul_film': 'Laskar Pelangi', 'genre': 'Drama', 'harga_tiket': 50000, 'jumlah_tiket': 75, 'tanggal': '2025-06-02', 'kota': 'SMG', 'jam_tayang': '14:30', 'studio': 'C'},
{'judul_film': 'Frozen II', 'genre': 'Horor', 'harga_tiket': 80000, 'jumlah_tiket': 123, 'tanggal': '2025-06-02', 'kota': 'JOGJA', 'jam_tayang': '20:00', 'studio': 'B'},
{'judul_film': 'Black Panther', 'genre': 'Komedi', 'harga_tiket': 80000, 'jumlah_tiket': 93, 'tanggal': '2025-06-04', 'kota': 'surabaya', 'jam_tayang': '16:00', 'studio': 'D'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Action', 'harga_tiket': 50000, 'jumlah_tiket': 68, 'tanggal': '2025-06-07', 'kota': 'SBY', 'jam_tayang': '22:00', 'studio': 'D'},
{'judul_film': 'Interstellar', 'genre': 'Komedi', 'harga_tiket': 60000, 'jumlah_tiket': 142, 'tanggal': '2025-06-15', 'kota': 'Makassar', 'jam_tayang': '20:00', 'studio': 'A'},
{'judul_film': 'Your Name', 'genre': 'Sci-Fi', 'harga_tiket': 55000, 'jumlah_tiket': 136, 'tanggal': '2025-06-01', 'kota': 'bandung', 'jam_tayang': '22:00', 'studio': 'B'},
{'judul_film': 'Parasite', 'genre': 'Action', 'harga_tiket': 60000, 'jumlah_tiket': 103, 'tanggal': '2025-06-07', 'kota': 'JAKARTA', 'jam_tayang': '22:00', 'studio': 'C'},
{'judul_film': 'Spiderman: Far From Home', 'genre': 'Komedi', 'harga_tiket': 80000, 'jumlah_tiket': 90, 'tanggal': '2025-06-02', 'kota': 'SBY', 'jam_tayang': '20:00', 'studio': 'C'},
{'judul_film': 'Black Panther', 'genre': 'Sci-Fi', 'harga_tiket': 80000, 'jumlah_tiket': 103, 'tanggal': '2025-06-11', 'kota': 'yogyakarta', 'jam_tayang': '20:00', 'studio': 'C'},
{'judul_film': 'Laskar Pelangi', 'genre': 'Komedi', 'harga_tiket': 65000, 'jumlah_tiket': 71, 'tanggal': '2025-06-07', 'kota': 'jakarta', 'jam_tayang': '14:30', 'studio': 'A'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Drama', 'harga_tiket': 60000, 'jumlah_tiket': 108, 'tanggal': '2025-06-11', 'kota': 'SEMARANG', 'jam_tayang': '19:30', 'studio': 'B'},
{'judul_film': 'Conjuring The Devil Made Me Do It', 'genre': 'Horor', 'harga_tiket': 60000, 'jumlah_tiket': 136, 'tanggal': '2025-06-01', 'kota': 'SMG', 'jam_tayang': '16:00', 'studio': 'D'},
{'judul_film': 'The Avengers Assemble', 'genre': 'Drama', 'harga_tiket': 75000, 'jumlah_tiket': 80, 'tanggal': '2025-06-13', 'kota': 'Surabaya', 'jam_tayang': '14:30', 'studio': 'B'},
{'judul_film': 'Spiderman: Homecoming', 'genre': 'Action', 'harga_tiket': 65000, 'jumlah_tiket': 100, 'tanggal': '2025-06-15', 'kota': 'SMG', 'jam_tayang': '18:00', 'studio': 'C'},
{'judul_film': 'Toy Story 4', 'genre': 'Action', 'harga_tiket': 60000, 'jumlah_tiket': 73, 'tanggal': '2025-06-06', 'kota': 'bandung', 'jam_tayang': '14:30', 'studio': 'B'},
{'judul_film': 'Frozen II', 'genre': 'Sci-Fi', 'harga_tiket': 55000, 'jumlah_tiket': 76, 'tanggal': '2025-06-01', 'kota': 'bandung', 'jam_tayang': '22:00', 'studio': 'A'},
{'judul_film': 'Frozen II', 'genre': 'Komedi', 'harga_tiket': 60000, 'jumlah_tiket': 82, 'tanggal': '2025-06-02', 'kota': 'BANDUNG', 'jam_tayang': '21:00', 'studio': 'A'},
{'judul_film': 'Doctor Strange: Multiverse of Madness', 'genre': 'Drama', 'harga_tiket': 55000, 'jumlah_tiket': 107, 'tanggal': '2025-06-05', 'kota': 'YOGYAKARTA', 'jam_tayang': '21:00', 'studio': 'D'}
]
df = pd.DataFrame(data)
df["pendapatan"] = df["harga_tiket"] * df["jumlah_tiket"]
pendapatan_per_genre = df.groupby("genre")["pendapatan"].sum().sort_values(ascending=False).to_dict()
print("Soal 1:", pendapatan_per_genre)
rata_rata_harga_per_genre = df.groupby("genre")["harga_tiket"].mean().round(2).to_dict()
print("Soal 2:", rata_rata_harga_per_genre)
tiket_per_tanggal = df.groupby("tanggal")["jumlah_tiket"].sum()
tanggal_terbanyak = tiket_per_tanggal.idxmax()
print("Soal 3:", tanggal_terbanyak, tiket_per_tanggal.max())
ALIAS = {"sby": "Surabaya", "surabaya": "Surabaya", "smg": "Semarang", "semarang": "Semarang",
"jkt": "Jakarta", "jakarta": "Jakarta", "jogja": "Yogyakarta", "yogyakarta": "Yogyakarta",
"makassar": "Makassar", "medan": "Medan", "bandung": "Bandung"}
df["kota_bersih"] = df["kota"].str.strip().str.lower().map(ALIAS)
assert df["kota_bersih"].notna().all()
judul_unik = df.groupby("kota_bersih")["judul_film"].nunique().sort_values(ascending=False)
kota_variasi_tertinggi = judul_unik[judul_unik == judul_unik.max()].index.tolist()
print("Soal 4 (raw column, WRONG):", df.groupby("kota")["judul_film"].nunique().nlargest(3).to_dict())
print("Soal 4:", kota_variasi_tertinggi, judul_unik.max())
pendapatan_per_film = df.groupby("judul_film")["pendapatan"].sum().sort_values(ascending=False)
film_teruntung = pendapatan_per_film.idxmax()
print("Soal 5:", film_teruntung, pendapatan_per_film.max())
genres_per_film = df.groupby("judul_film")["genre"].unique()
print("Bonus:", {f: list(g) for f, g in genres_per_film.items() if len(g) >= 4})
print("Bonus: films with more than one genre:", (genres_per_film.str.len() > 1).sum(), "of", len(genres_per_film))
fig, ax = plt.subplots(1, 2, figsize=(13, 4.8), gridspec_kw={"width_ratios": [1.25, 1]})
raw = df.groupby("kota")["judul_film"].nunique().sort_values()
ax[0].barh(raw.index, raw.values, color="#bbb")
for i, (k, v) in enumerate(raw.items()): ax[0].text(v + .1, i, str(v), va="center", fontsize=8)
ax[0].set_title("Raw 'kota' column: 24 spellings of 7 cities"); ax[0].set_xlabel("unique film titles")
ax[0].tick_params(axis="y", labelsize=8)
cl = judul_unik.sort_values()
ax[1].barh(cl.index, cl.values, color=["#c0392b" if v == cl.max() else "#2471a3" for v in cl.values])
for i, v in enumerate(cl.values): ax[1].text(v + .1, i, str(v), va="center")
ax[1].set_title("After normalising the city names"); ax[1].set_xlabel("unique film titles")
plt.tight_layout(); plt.savefig("figures/city_cleaning.png", dpi=150); plt.close()