PBL (BIG DATA & DATABASE ADVANCE)

 

PROYEK  PENGELOLAAN & VISUALISASI DATA DENGAN  
MONGODB DAN PYTHON BERBASIS WEB


    Visualisasi data adalah langkah penting dalam memahami informasi yang kompleks. Dengan alat yang tepat, data dapat disulap menjadi grafik atau dashboard interaktif yang membantu pengambilan keputusan. Salah satu alat terbaik untuk tugas ini adalah Tableau. Berikut adalah langkah-langkah sederhana untuk membuat visualisasi data menggunakan Tableau:

Dataset

    Dataset yang digunakan adalah Netflix (Movies & TV Shows). Dataset ini berisi informasi mengenai berbagai konten yang tersedia di platform Netflix, seperti film, acara TV, genre, negara asal, dan lainnya.

Download dataset Netflix TV Shows & Movie (https://public.tableau.com/app/learn/sample-data) lalu simpan dalam folder



Mengimpor Dataset ke MongoDB

A. Buka VSCode lalu buatlah sebuah file baru dengan nama import_to_mongo.py.


Kode di atas adalah sebuah skrip Python yang bertujuan untuk mengimpor data dari file Excel, memproses data tersebut, dan menyimpannya ke dalam database MongoDB.

B. Impor data dari file Excel dan membaca dataset film atau acara TV dari file Excel dengan kode:

import pandas as pd
from pymongo import MongoClient
import datetime

# Path ke file dataset
file_path = "E:/jupyter-notebook/Lib/site-packages/Netflix_Project/netflix_titles.xlsx"

# Membaca file Excel
try:
    df = pd.read_excel(file_path, engine='openpyxl')
    print("File Excel berhasil dibaca!")
except Exception as e:
    print(f"Error saat membaca file Excel: {e}")
    exit()

# Konversi kolom bertipe datetime.time ke string
for column in df.columns:
    if df[column].apply(lambda x: isinstance(x, (datetime.datetime, datetime.time))).any():
        print(f"Kolom '{column}' mengandung datetime atau time, mengonversi ke string...")
        df[column] = df[column].apply(lambda x: str(x) if isinstance(x, (datetime.datetime, datetime.time)) else x)

# Cek tipe data setelah konversi
print("Tipe data dalam DataFrame setelah konversi:")
print(df.dtypes)

# Koneksi ke MongoDB
try:
    client = MongoClient("mongodb://localhost:27017/")  # Default MongoDB URL
    db = client["netflix_db"]
    collection = db["netflix_titles"]
    print("Koneksi ke MongoDB berhasil!")
except Exception as e:
    print(f"Error saat menghubungkan ke MongoDB: {e}")
    exit()

# Simpan data ke MongoDB
try:
    data = df.to_dict(orient="records")
    collection.insert_many(data)  # Menyimpan data dalam bentuk batch
    print("Data berhasil disimpan ke MongoDB!")
except Exception as e:
    print(f"Error saat menyimpan data ke MongoDB: {e}")  # Menampilkan pesan error lebih lengkap

C. Setelah memasukan kode diatas maka jalankan kode tersebut di terminal dengan python import_to_mongo.py


D. 
Jika proses berhasil, data akan disimpan ke dalam database bernama netflix_db pada koleksi netflix_title


Membuat aplikasi CRUD menggunakan python

A. Membuat struktur folder proyek di di dalam folder utama Netflix_Project/:



B. Buat File Utama app.py, lalu Tambahkan kode Flask dasar untuk memulai aplikasi CRUD

from flask import Flask, render_template, request, redirect, url_for
from pymongo import MongoClient
from bson.objectid import ObjectId

# Koneksi ke MongoDB
client = MongoClient('mongodb://localhost:27017/')  # Sesuaikan jika menggunakan host lain
db = client['netflix_db']  # Mengakses database netflix_db
collection = db['netflix_titles']  # Mengakses koleksi netflix_titles

app = Flask(__name__)

# Halaman utama untuk menampilkan data
@app.route('/')
def index():
    titles = collection.find()  # Mengambil semua data dari MongoDB
    # Konversi ObjectId ke string untuk setiap judul
    titles = [{**title, 'id_str': str(title['_id'])} for title in titles]
    return render_template('index.html', titles=titles)

# Halaman untuk menambah data baru (Create)
@app.route('/create', methods=['GET', 'POST'])
def create():
    if request.method == 'POST':
        title = request.form['title']
        director = request.form['director']
        genre = request.form['genre']
        release_year = request.form['release_year']
        
        data = {
            'title': title,
            'director': director,
            'genre': genre,
            'release_year': int(release_year)
        }
        collection.insert_one(data)
        return redirect(url_for('index'))
    return render_template('create.html')

# Halaman untuk memperbarui data (Update)
@app.route('/update/<title_id>', methods=['GET', 'POST'])
def update(title_id):
    title = collection.find_one({'_id': ObjectId(title_id)})
    title['id_str'] = str(title['_id'])  # Konversi ID ke string
    if request.method == 'POST':
        title_name = request.form['title']
        director = request.form['director']
        genre = request.form['genre']
        release_year = request.form['release_year']
        
        collection.update_one(
            {'_id': ObjectId(title_id)},
            {'$set': {'title': title_name, 'director': director, 'genre': genre, 'release_year': int(release_year)}}
        )
        return redirect(url_for('index'))
    return render_template('update.html', title=title)

# Halaman untuk menghapus data (Delete)
@app.route('/delete/<title_id>', methods=['GET', 'POST'])
def delete(title_id):
    collection.delete_one({'_id': ObjectId(title_id)})
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)

C. Di dalam folder Netflix_project, buat folder templates yang berisi (index.html, create.html, update.html) untuk menyimpan file HTML.

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Netflix Titles</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }
        header {
            background-color: #f8f9fa;
            padding: 1rem;
            text-align: center;
            border-bottom: 1px solid #ddd;
        }
        header h1 {
            margin: 0;
            color: #333;
        }
        header p {
            margin: 0;
            font-size: 1rem;
            color: #555;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 1rem;
        }
        th,
        td {
            padding: 0.5rem;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        tr:nth-child(even) {
            background-color: #f9f9f9;
        }
        a {
            text-decoration: none;
            color: #007bff;
        }
        a:hover {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <!-- Header Section -->
    <header>
        <h1>Netflix Titles</h1>
        <p>Nama: Sabilla Ardani Putri</p>
        <p>NIM: 8801202211</p>
    </header>
    <!-- Main Content -->
    <a href="{{ url_for('create') }}">Add New Title</a>
    <table border="1">
        <tr>
            <th>Title</th>
            <th>Director</th>
            <th>Genre</th>
            <th>Release Year</th>
            <th>Actions</th>
        </tr>
        {% for title in titles %}
        <tr>
            <td>{{ title['title'] }}</td>
            <td>{{ title['director'] }}</td>
            <td>{{ title['genre'] }}</td>
            <td>{{ title['release_year'] }}</td>
            <td>
                <a href="{{ url_for('update', title_id=title['id_str']) }}">Edit</a> |
                <a href="{{ url_for('delete', title_id=title['id_str']) }}">Delete</a>
            </td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>

create.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create New Title</title>
</head>
<body>
    <h1>Add New Netflix Title</h1>
    <form method="POST">
        <label for="title">Title:</label><br>
        <input type="text" id="title" name="title" required><br>
        <label for="director">Director:</label><br>
        <input type="text" id="director" name="director" required><br>
        <label for="genre">Genre:</label><br>
        <input type="text" id="genre" name="genre" required><br>
        <label for="release_year">Release Year:</label><br>
        <input type="number" id="release_year" name="release_year" required><br>
        <button type="submit">Submit</button>
    </form>
    <a href="{{ url_for('index') }}">Back to List</a>
</body>
</html>

update.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Update Title</title>
</head>
<body>
    <h1>Update Netflix Title</h1>
    <form method="POST">
        <label for="title">Title:</label><br>
        <input type="text" id="title" name="title" value="{{ title['title'] }}" required><br>
        <label for="director">Director:</label><br>
        <input type="text" id="director" name="director" value="{{ title['director'] }}" required><br>
        <label for="genre">Genre:</label><br>
        <input type="text" id="genre" name="genre" value="{{ title['genre'] }}" required><br>
        <label for="release_year">Release Year:</label><br>
        <input type="number" id="release_year" name="release_year" value="{{ title['release_year'] }}" required><br>
        <button type="submit">Update</button>
    </form>
    <a href="{{ url_for('index') }}">Back to List</a>
</body>
</html>

Jalankan server Flask dengan perintah berikut di terminal dengan (python app.py)Flask akan berjalan di http://127.0.0.1:5000


tampilan wesite


bagian edit di dalam tampilan tabel netflix titles


Visualisasi data

Untuk membuat visualisasi data berdasarkan dataset Netflix yang sudah disimpan di MongoDB, kita akan memuat file baru di direktori proyek dengan nama visualization.py. File ini berisi kode untuk Mengambil data dari MongoDB, Mengolah data menggunakan Pandas, Membuat visualisasi menggunakan Matplotlib dan Seaborn, lalu tambahkan skrip berikut:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from pymongo import MongoClient

# Koneksi MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["netflix_db"]
collection = db["netflix_titles"]  # Ganti 'netflix_data' menjadi 'netflix_titles'

# Load data dari MongoDB
data = pd.DataFrame(list(collection.find()))

# Cek apakah data berhasil dimuat
if data.empty:
    print("Data kosong, periksa koleksi MongoDB.")
else:
    print("Data berhasil dimuat!")

    # Tampilkan nama kolom untuk memastikan kolom yang dibutuhkan ada
    print("Nama kolom dalam DataFrame:")
    print(data.columns)

    # a) Berapa banyak movie dan tvshow
    if "type" in data.columns:
        content_type = data["type"].value_counts()
        content_type.plot(kind="bar", title="Jumlah Movie dan TV Show")
        plt.show()
    else:
        print("Kolom 'type' tidak ditemukan!")

    # b) Kategorikan berdasarkan genre
    if "listed_in" in data.columns:
        genres = data["listed_in"].str.split(", ").explode()
        genre_count = genres.value_counts()
        genre_count.plot(kind="bar", title="Genre Terbanyak")
        plt.show()
    else:
        print("Kolom 'listed_in' tidak ditemukan!")

    # c) Visualisasi konten berdasarkan negara
    if "country" in data.columns:
        country_count = data["country"].value_counts().head(10)
        country_count.plot(kind="bar", title="Top 10 Negara dengan Konten Terbanyak")
        plt.show()
    else:
        print("Kolom 'country' tidak ditemukan!")

    # d) Jumlah konten dari tahun ke tahun
    if "release_year" in data.columns:
        release_year_count = data["release_year"].value_counts().sort_index()
        release_year_count.plot(kind="line", title="Jumlah Konten per Tahun")
        plt.show()
    else:
        print("Kolom 'release_year' tidak ditemukan!")

    # e) Rata-rata durasi konten
    if "duration_seasons" in data.columns:
        data["duration_num"] = pd.to_numeric(data["duration_seasons"].str.extract("(\d+)")[0], errors="coerce")
        avg_duration = data.groupby("type")["duration_num"].mean()
        avg_duration.plot(kind="bar", title="Rata-rata Durasi Konten")
        plt.show()
    else:
        print("Kolom 'duration_seasons' tidak ditemukan!")

    # f) Berdasarkan rating
    if "rating" in data.columns:
        rating_count = data["rating"].value_counts()
        rating_count.plot(kind="bar", title="Rating Terbanyak di Netflix")
        plt.show()
    else:
        print("Kolom 'rating' tidak ditemukan!")

Menjalankan visualisasi di terminal

Pastikan Anda berada di direktori yang sama dengan file visualization.py, kemudian jalankan perintah (python visualization.py)


Saat file visualization.py dijalankan, grafik-grafik akan ditampilkan satu per satu menggunakan










Komentar

Postingan populer dari blog ini

Local File Inclusion (LFI) & Remote File Inclusion (RFI) - Sabilla Ardani Putri

TIDAK TERPAKAI - Footprinting dan Reconnaissance menggunakan Whois, Web History, Google Dork, GHDB

Manajemen Data Master - Sabilla Ardani Putri