<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://kontenbelajar.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Aditya</id>
	<title>belajarwiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://kontenbelajar.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Aditya"/>
	<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php/Special:Contributions/Aditya"/>
	<updated>2026-10-19T23:07:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Thumbnail-Preserving_Encryption_(TPE)&amp;diff=422</id>
		<title>Thumbnail-Preserving Encryption (TPE)</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Thumbnail-Preserving_Encryption_(TPE)&amp;diff=422"/>
		<updated>2026-10-14T07:22:02Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;Thumbnail-Preserving Encryption (TPE) adalah teknik kriptografi khusus yang mengenkripsi gambar digital agar informasi detailnya aman, namun tetap mempertahankan tampilan visu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thumbnail-Preserving Encryption (TPE) adalah teknik kriptografi khusus yang mengenkripsi gambar digital agar informasi detailnya aman, namun tetap mempertahankan tampilan visual thumbnail atau pratinjau aslinya.&lt;br /&gt;
&lt;br /&gt;
* [[Paper Deng]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=421</id>
		<title>Pengambilan-data-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=421"/>
		<updated>2026-09-30T07:05:15Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 1. Folder project&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 2. API&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
url = (&lt;br /&gt;
    &amp;quot;https://api.bsky.app/&amp;quot;&lt;br /&gt;
    &amp;quot;xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 3. Request&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;:&lt;br /&gt;
            &amp;quot;application/json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;:&lt;br /&gt;
            &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 4. Validasi response&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        f&amp;quot;HTTP {response.status_code}: &amp;quot;&lt;br /&gt;
        f&amp;quot;{response.text[:300]}&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
data = response.json()&lt;br /&gt;
&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 5. Simpan JSON asli&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 6. Ubah ke tabel&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 7. Simpan CSV raw&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 8. Pemeriksaan&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Ukuran dataset:&amp;quot;,&lt;br /&gt;
    df_raw.shape&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
display(&lt;br /&gt;
    df_raw.head()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;PROJECT = Path(&amp;quot;/media/Kuliah/BigDataFisip&amp;quot;)&amp;lt;/b&amp;gt; sesuaikan saja dengan PATH yang kalian miliki.&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;&amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&amp;lt;/b&amp;gt; sesuaikan saja tentang topik apa yang dicari.&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[Big Data Fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=420</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=420"/>
		<updated>2026-09-30T07:05:06Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
==Data Cleaning==&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;br /&gt;
&lt;br /&gt;
Cek nama variabel&lt;br /&gt;
 df.columns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cek kondisi data===&lt;br /&gt;
 df.info()&lt;br /&gt;
 df.head()&lt;br /&gt;
 df.sample(5)&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Untuk kasus saya, ada 15 posting tidak mempunyai display_name, namun kita cek pakah masih memiliki username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek lagi&lt;br /&gt;
 df[&amp;quot;display_name&amp;quot;].isna().sum()&lt;br /&gt;
&lt;br /&gt;
Harus menghasilkan 0&lt;br /&gt;
&lt;br /&gt;
Berarti dalam kasus ini display_name tidak terlalu penting karena masih ada username.&lt;br /&gt;
&lt;br /&gt;
===Cek apakah ada duplicate===&lt;br /&gt;
 df.duplicated().sum()&lt;br /&gt;
&lt;br /&gt;
Klo pada kasus saya, id unik nya adalah uri,jadi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.duplicated(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
).sum()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kode cleaning nya adalah&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kalau satu posting masuk dua kali, analisis kita dapat menghitung satu opini atau satu engagement dua kali.&lt;br /&gt;
&lt;br /&gt;
===Rapihkan display_name===&lt;br /&gt;
Beberapa nama mungkin memiliki spasi tambahan.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita rapihkan juga username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perbaiki type tanggal===&lt;br /&gt;
Kita cek tipe datanya&lt;br /&gt;
 df[&amp;quot;created_at&amp;quot;].dtype&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya = object, berarti masih dianggap teks, jadi harus diubah ke tipe waktu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah UTC ke waktu Jakarta===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&amp;quot;created_at&amp;quot;, &amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rapihkan kolom bahasa===&lt;br /&gt;
 df[&amp;quot;language&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
Perbaiki&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;language_primary&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Pastikan reply, repost dan like benar-benar numerik===&lt;br /&gt;
Cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].dtypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jika masih belum angka&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jika ada URL terambil===&lt;br /&gt;
Buat variabel, barangkali nanti url tersebut dibutuhkan&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_url&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Deteksi Hastag===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_hashtag&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
==Preprocessing==&lt;br /&gt;
===Buat Clean Text===&lt;br /&gt;
Kita mulai masuk ke preprocessing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hapus URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nanti hasilnya misal: &amp;lt;b&amp;gt;Climate change is real https://example.com&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Climate change is real&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Hilangkan mention===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namun mention tidak selalu harus dibuang. Kalau kita ingin melakukan network analysis, mention justru merupakan data yang penting.&lt;br /&gt;
&lt;br /&gt;
===Hastag===&lt;br /&gt;
Jangan buang katanya, namun tanda &amp;quot;#&amp;quot; saja&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah menjadi lowercase===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ini penting agar komputer tidak menganggap kata yang sama namun misal ada huruf kapital, sebagai kata berbeda.&lt;br /&gt;
&lt;br /&gt;
===Rapikan line break dan spasi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bandingkan sebelum dan sesudah===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;text&amp;quot;,&lt;br /&gt;
        &amp;quot;text_clean&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Buat variabel engagement===&lt;br /&gt;
Misal kita perlu untuk menghitung hubungannya.&lt;br /&gt;
Kita definisikan secara sederhana:Engagement = Reply + Repost + Like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ini adalah definisi operasional untuk latihan, bukan definisi universal engagement. Kalau penelitian sebenarnya, Anda harus menjelaskan mengapa reply, repost, dan like dijumlahkan dan apakah bobotnya memang seharusnya sama.&lt;br /&gt;
&lt;br /&gt;
===Buat jumlah kata===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;word_count&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Buat variabel tanggal dan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaning = memperbaiki data.&lt;br /&gt;
Preprocessing = membuat data menjadi lebih siap untuk analisis.&lt;br /&gt;
&lt;br /&gt;
===Validasi===&lt;br /&gt;
Jumlah data:&lt;br /&gt;
 len(df)&lt;br /&gt;
&lt;br /&gt;
Missing value:&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Duplicate:&lt;br /&gt;
 df.duplicated(subset=&amp;quot;uri&amp;quot;).sum()&lt;br /&gt;
&lt;br /&gt;
Statistik engagement:&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
Tampilkan hasil:&lt;br /&gt;
 df.head()&lt;br /&gt;
&lt;br /&gt;
Kode berhasil dijalankan belum berarti data sudah benar. Kita tetap harus memeriksa hasil.&lt;br /&gt;
&lt;br /&gt;
===Simpan===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Kode lengkap==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 1. LOAD DATA&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. DUPLICATE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. MISSING DISPLAY NAME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. DATE / TIME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 5. LANGUAGE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 6. NUMERIC VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 7. INFORMATION FROM ORIGINAL TEXT&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 8. TEXT CLEANING&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove URL&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove mentions&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Keep hashtag word, remove #&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Lowercase&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove extra whitespace&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 9. DERIVED VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 10. VALIDATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Jumlah data:&amp;quot;, len(df))&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nMissing value:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df.isna().sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nDuplicate URI:&amp;quot;,&lt;br /&gt;
    df.duplicated(&lt;br /&gt;
        subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
    ).sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nStatistik engagement:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 11. SAVE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nData bersih berhasil disimpan.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analisis yang bisa dilakukan==&lt;br /&gt;
===Seberapa tinggi engagement?===&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Posting dengan engagement tertinggi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
top10 = (&lt;br /&gt;
    df.sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;,&lt;br /&gt;
        ascending=False&lt;br /&gt;
    )&lt;br /&gt;
    [&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;username&amp;quot;,&lt;br /&gt;
            &amp;quot;text_clean&amp;quot;,&lt;br /&gt;
            &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
            &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
            &amp;quot;like_count&amp;quot;,&lt;br /&gt;
            &amp;quot;engagement&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
    .head(10)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi Top 10 Engagement===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
top10_plot = (&lt;br /&gt;
    df.nlargest(&lt;br /&gt;
        10,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10_plot.plot(&lt;br /&gt;
    x=&amp;quot;username&amp;quot;,&lt;br /&gt;
    y=&amp;quot;engagement&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;10 Posting dengan Engagement Tertinggi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Engagement&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Akun&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Akun paling aktif===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    &amp;quot;username&amp;quot;&lt;br /&gt;
].value_counts().head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aktivitas berdasarkan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam = (&lt;br /&gt;
    df[&amp;quot;hour&amp;quot;]&lt;br /&gt;
    .value_counts()&lt;br /&gt;
    .sort_index()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
posting_per_jam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visualisasi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam.plot(&lt;br /&gt;
    kind=&amp;quot;bar&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Jumlah Posting per Jam&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Jam (WIB)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Jumlah Posting&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kata yang sering muncul===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import Counter&lt;br /&gt;
&lt;br /&gt;
semua_teks = &amp;quot; &amp;quot;.join(&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kata = re.findall(&lt;br /&gt;
    r&amp;quot;[a-zA-Z][a-zA-Z'-]+&amp;quot;,&lt;br /&gt;
    semua_teks&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
stopwords = {&lt;br /&gt;
    &amp;quot;the&amp;quot;, &amp;quot;and&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;of&amp;quot;,&lt;br /&gt;
    &amp;quot;a&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;for&amp;quot;,&lt;br /&gt;
    &amp;quot;that&amp;quot;, &amp;quot;it&amp;quot;, &amp;quot;on&amp;quot;, &amp;quot;with&amp;quot;,&lt;br /&gt;
    &amp;quot;are&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;as&amp;quot;, &amp;quot;this&amp;quot;,&lt;br /&gt;
    &amp;quot;we&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;they&amp;quot;,&lt;br /&gt;
    &amp;quot;have&amp;quot;, &amp;quot;has&amp;quot;, &amp;quot;was&amp;quot;,&lt;br /&gt;
    &amp;quot;were&amp;quot;, &amp;quot;not&amp;quot;, &amp;quot;but&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    # kata pencarian&lt;br /&gt;
    &amp;quot;climate&amp;quot;,&lt;br /&gt;
    &amp;quot;change&amp;quot;,&lt;br /&gt;
    &amp;quot;climatechange&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kata_bersih = [&lt;br /&gt;
    k&lt;br /&gt;
    for k in kata&lt;br /&gt;
    if k not in stopwords&lt;br /&gt;
    and len(k) &amp;gt; 2&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
frekuensi = Counter(&lt;br /&gt;
    kata_bersih&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
frekuensi.most_common(20)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi 15 kata teratas===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
freq_df = pd.DataFrame(&lt;br /&gt;
    frekuensi.most_common(15),&lt;br /&gt;
    columns=[&lt;br /&gt;
        &amp;quot;word&amp;quot;,&lt;br /&gt;
        &amp;quot;frequency&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df = freq_df.sort_values(&lt;br /&gt;
    &amp;quot;frequency&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df.plot(&lt;br /&gt;
    x=&amp;quot;word&amp;quot;,&lt;br /&gt;
    y=&amp;quot;frequency&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;15 Kata yang Sering Muncul&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Frekuensi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Kata&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[Big Data Fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=419</id>
		<title>Pengambilan-data-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=419"/>
		<updated>2026-09-30T07:04:09Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 1. Folder project&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 2. API&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
url = (&lt;br /&gt;
    &amp;quot;https://api.bsky.app/&amp;quot;&lt;br /&gt;
    &amp;quot;xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 3. Request&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;:&lt;br /&gt;
            &amp;quot;application/json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;:&lt;br /&gt;
            &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 4. Validasi response&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        f&amp;quot;HTTP {response.status_code}: &amp;quot;&lt;br /&gt;
        f&amp;quot;{response.text[:300]}&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
data = response.json()&lt;br /&gt;
&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 5. Simpan JSON asli&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 6. Ubah ke tabel&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 7. Simpan CSV raw&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 8. Pemeriksaan&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Ukuran dataset:&amp;quot;,&lt;br /&gt;
    df_raw.shape&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
display(&lt;br /&gt;
    df_raw.head()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;PROJECT = Path(&amp;quot;/media/Kuliah/BigDataFisip&amp;quot;)&amp;lt;/b&amp;gt; sesuaikan saja dengan PATH yang kalian miliki.&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;&amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&amp;lt;/b&amp;gt; sesuaikan saja tentang topik apa yang dicari.&lt;br /&gt;
&lt;br /&gt;
* [[Big Data Fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=418</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=418"/>
		<updated>2026-09-30T07:04:02Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
==Data Cleaning==&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;br /&gt;
&lt;br /&gt;
Cek nama variabel&lt;br /&gt;
 df.columns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cek kondisi data===&lt;br /&gt;
 df.info()&lt;br /&gt;
 df.head()&lt;br /&gt;
 df.sample(5)&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Untuk kasus saya, ada 15 posting tidak mempunyai display_name, namun kita cek pakah masih memiliki username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek lagi&lt;br /&gt;
 df[&amp;quot;display_name&amp;quot;].isna().sum()&lt;br /&gt;
&lt;br /&gt;
Harus menghasilkan 0&lt;br /&gt;
&lt;br /&gt;
Berarti dalam kasus ini display_name tidak terlalu penting karena masih ada username.&lt;br /&gt;
&lt;br /&gt;
===Cek apakah ada duplicate===&lt;br /&gt;
 df.duplicated().sum()&lt;br /&gt;
&lt;br /&gt;
Klo pada kasus saya, id unik nya adalah uri,jadi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.duplicated(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
).sum()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kode cleaning nya adalah&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kalau satu posting masuk dua kali, analisis kita dapat menghitung satu opini atau satu engagement dua kali.&lt;br /&gt;
&lt;br /&gt;
===Rapihkan display_name===&lt;br /&gt;
Beberapa nama mungkin memiliki spasi tambahan.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita rapihkan juga username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perbaiki type tanggal===&lt;br /&gt;
Kita cek tipe datanya&lt;br /&gt;
 df[&amp;quot;created_at&amp;quot;].dtype&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya = object, berarti masih dianggap teks, jadi harus diubah ke tipe waktu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah UTC ke waktu Jakarta===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&amp;quot;created_at&amp;quot;, &amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rapihkan kolom bahasa===&lt;br /&gt;
 df[&amp;quot;language&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
Perbaiki&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;language_primary&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Pastikan reply, repost dan like benar-benar numerik===&lt;br /&gt;
Cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].dtypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jika masih belum angka&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jika ada URL terambil===&lt;br /&gt;
Buat variabel, barangkali nanti url tersebut dibutuhkan&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_url&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Deteksi Hastag===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_hashtag&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
==Preprocessing==&lt;br /&gt;
===Buat Clean Text===&lt;br /&gt;
Kita mulai masuk ke preprocessing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hapus URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nanti hasilnya misal: &amp;lt;b&amp;gt;Climate change is real https://example.com&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Climate change is real&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Hilangkan mention===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namun mention tidak selalu harus dibuang. Kalau kita ingin melakukan network analysis, mention justru merupakan data yang penting.&lt;br /&gt;
&lt;br /&gt;
===Hastag===&lt;br /&gt;
Jangan buang katanya, namun tanda &amp;quot;#&amp;quot; saja&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah menjadi lowercase===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ini penting agar komputer tidak menganggap kata yang sama namun misal ada huruf kapital, sebagai kata berbeda.&lt;br /&gt;
&lt;br /&gt;
===Rapikan line break dan spasi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bandingkan sebelum dan sesudah===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;text&amp;quot;,&lt;br /&gt;
        &amp;quot;text_clean&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Buat variabel engagement===&lt;br /&gt;
Misal kita perlu untuk menghitung hubungannya.&lt;br /&gt;
Kita definisikan secara sederhana:Engagement = Reply + Repost + Like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ini adalah definisi operasional untuk latihan, bukan definisi universal engagement. Kalau penelitian sebenarnya, Anda harus menjelaskan mengapa reply, repost, dan like dijumlahkan dan apakah bobotnya memang seharusnya sama.&lt;br /&gt;
&lt;br /&gt;
===Buat jumlah kata===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;word_count&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Buat variabel tanggal dan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaning = memperbaiki data.&lt;br /&gt;
Preprocessing = membuat data menjadi lebih siap untuk analisis.&lt;br /&gt;
&lt;br /&gt;
===Validasi===&lt;br /&gt;
Jumlah data:&lt;br /&gt;
 len(df)&lt;br /&gt;
&lt;br /&gt;
Missing value:&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Duplicate:&lt;br /&gt;
 df.duplicated(subset=&amp;quot;uri&amp;quot;).sum()&lt;br /&gt;
&lt;br /&gt;
Statistik engagement:&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
Tampilkan hasil:&lt;br /&gt;
 df.head()&lt;br /&gt;
&lt;br /&gt;
Kode berhasil dijalankan belum berarti data sudah benar. Kita tetap harus memeriksa hasil.&lt;br /&gt;
&lt;br /&gt;
===Simpan===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Kode lengkap==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 1. LOAD DATA&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. DUPLICATE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. MISSING DISPLAY NAME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. DATE / TIME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 5. LANGUAGE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 6. NUMERIC VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 7. INFORMATION FROM ORIGINAL TEXT&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 8. TEXT CLEANING&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove URL&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove mentions&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Keep hashtag word, remove #&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Lowercase&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove extra whitespace&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 9. DERIVED VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 10. VALIDATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Jumlah data:&amp;quot;, len(df))&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nMissing value:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df.isna().sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nDuplicate URI:&amp;quot;,&lt;br /&gt;
    df.duplicated(&lt;br /&gt;
        subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
    ).sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nStatistik engagement:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 11. SAVE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nData bersih berhasil disimpan.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analisis yang bisa dilakukan==&lt;br /&gt;
===Seberapa tinggi engagement?===&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Posting dengan engagement tertinggi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
top10 = (&lt;br /&gt;
    df.sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;,&lt;br /&gt;
        ascending=False&lt;br /&gt;
    )&lt;br /&gt;
    [&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;username&amp;quot;,&lt;br /&gt;
            &amp;quot;text_clean&amp;quot;,&lt;br /&gt;
            &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
            &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
            &amp;quot;like_count&amp;quot;,&lt;br /&gt;
            &amp;quot;engagement&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
    .head(10)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi Top 10 Engagement===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
top10_plot = (&lt;br /&gt;
    df.nlargest(&lt;br /&gt;
        10,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10_plot.plot(&lt;br /&gt;
    x=&amp;quot;username&amp;quot;,&lt;br /&gt;
    y=&amp;quot;engagement&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;10 Posting dengan Engagement Tertinggi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Engagement&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Akun&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Akun paling aktif===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    &amp;quot;username&amp;quot;&lt;br /&gt;
].value_counts().head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aktivitas berdasarkan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam = (&lt;br /&gt;
    df[&amp;quot;hour&amp;quot;]&lt;br /&gt;
    .value_counts()&lt;br /&gt;
    .sort_index()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
posting_per_jam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visualisasi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam.plot(&lt;br /&gt;
    kind=&amp;quot;bar&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Jumlah Posting per Jam&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Jam (WIB)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Jumlah Posting&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kata yang sering muncul===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import Counter&lt;br /&gt;
&lt;br /&gt;
semua_teks = &amp;quot; &amp;quot;.join(&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kata = re.findall(&lt;br /&gt;
    r&amp;quot;[a-zA-Z][a-zA-Z'-]+&amp;quot;,&lt;br /&gt;
    semua_teks&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
stopwords = {&lt;br /&gt;
    &amp;quot;the&amp;quot;, &amp;quot;and&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;of&amp;quot;,&lt;br /&gt;
    &amp;quot;a&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;for&amp;quot;,&lt;br /&gt;
    &amp;quot;that&amp;quot;, &amp;quot;it&amp;quot;, &amp;quot;on&amp;quot;, &amp;quot;with&amp;quot;,&lt;br /&gt;
    &amp;quot;are&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;as&amp;quot;, &amp;quot;this&amp;quot;,&lt;br /&gt;
    &amp;quot;we&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;they&amp;quot;,&lt;br /&gt;
    &amp;quot;have&amp;quot;, &amp;quot;has&amp;quot;, &amp;quot;was&amp;quot;,&lt;br /&gt;
    &amp;quot;were&amp;quot;, &amp;quot;not&amp;quot;, &amp;quot;but&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    # kata pencarian&lt;br /&gt;
    &amp;quot;climate&amp;quot;,&lt;br /&gt;
    &amp;quot;change&amp;quot;,&lt;br /&gt;
    &amp;quot;climatechange&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kata_bersih = [&lt;br /&gt;
    k&lt;br /&gt;
    for k in kata&lt;br /&gt;
    if k not in stopwords&lt;br /&gt;
    and len(k) &amp;gt; 2&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
frekuensi = Counter(&lt;br /&gt;
    kata_bersih&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
frekuensi.most_common(20)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi 15 kata teratas===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
freq_df = pd.DataFrame(&lt;br /&gt;
    frekuensi.most_common(15),&lt;br /&gt;
    columns=[&lt;br /&gt;
        &amp;quot;word&amp;quot;,&lt;br /&gt;
        &amp;quot;frequency&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df = freq_df.sort_values(&lt;br /&gt;
    &amp;quot;frequency&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df.plot(&lt;br /&gt;
    x=&amp;quot;word&amp;quot;,&lt;br /&gt;
    y=&amp;quot;frequency&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;15 Kata yang Sering Muncul&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Frekuensi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Kata&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Big Data Fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=417</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=417"/>
		<updated>2026-09-30T04:31:10Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* =Hilangkan mention */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
==Data Cleaning==&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;br /&gt;
&lt;br /&gt;
Cek nama variabel&lt;br /&gt;
 df.columns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cek kondisi data===&lt;br /&gt;
 df.info()&lt;br /&gt;
 df.head()&lt;br /&gt;
 df.sample(5)&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Untuk kasus saya, ada 15 posting tidak mempunyai display_name, namun kita cek pakah masih memiliki username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek lagi&lt;br /&gt;
 df[&amp;quot;display_name&amp;quot;].isna().sum()&lt;br /&gt;
&lt;br /&gt;
Harus menghasilkan 0&lt;br /&gt;
&lt;br /&gt;
Berarti dalam kasus ini display_name tidak terlalu penting karena masih ada username.&lt;br /&gt;
&lt;br /&gt;
===Cek apakah ada duplicate===&lt;br /&gt;
 df.duplicated().sum()&lt;br /&gt;
&lt;br /&gt;
Klo pada kasus saya, id unik nya adalah uri,jadi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.duplicated(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
).sum()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kode cleaning nya adalah&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kalau satu posting masuk dua kali, analisis kita dapat menghitung satu opini atau satu engagement dua kali.&lt;br /&gt;
&lt;br /&gt;
===Rapihkan display_name===&lt;br /&gt;
Beberapa nama mungkin memiliki spasi tambahan.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita rapihkan juga username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perbaiki type tanggal===&lt;br /&gt;
Kita cek tipe datanya&lt;br /&gt;
 df[&amp;quot;created_at&amp;quot;].dtype&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya = object, berarti masih dianggap teks, jadi harus diubah ke tipe waktu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah UTC ke waktu Jakarta===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&amp;quot;created_at&amp;quot;, &amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rapihkan kolom bahasa===&lt;br /&gt;
 df[&amp;quot;language&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
Perbaiki&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;language_primary&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Pastikan reply, repost dan like benar-benar numerik===&lt;br /&gt;
Cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].dtypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jika masih belum angka&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jika ada URL terambil===&lt;br /&gt;
Buat variabel, barangkali nanti url tersebut dibutuhkan&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_url&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Deteksi Hastag===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_hashtag&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
==Preprocessing==&lt;br /&gt;
===Buat Clean Text===&lt;br /&gt;
Kita mulai masuk ke preprocessing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hapus URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nanti hasilnya misal: &amp;lt;b&amp;gt;Climate change is real https://example.com&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Climate change is real&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Hilangkan mention===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namun mention tidak selalu harus dibuang. Kalau kita ingin melakukan network analysis, mention justru merupakan data yang penting.&lt;br /&gt;
&lt;br /&gt;
===Hastag===&lt;br /&gt;
Jangan buang katanya, namun tanda &amp;quot;#&amp;quot; saja&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah menjadi lowercase===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ini penting agar komputer tidak menganggap kata yang sama namun misal ada huruf kapital, sebagai kata berbeda.&lt;br /&gt;
&lt;br /&gt;
===Rapikan line break dan spasi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bandingkan sebelum dan sesudah===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;text&amp;quot;,&lt;br /&gt;
        &amp;quot;text_clean&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Buat variabel engagement===&lt;br /&gt;
Misal kita perlu untuk menghitung hubungannya.&lt;br /&gt;
Kita definisikan secara sederhana:Engagement = Reply + Repost + Like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ini adalah definisi operasional untuk latihan, bukan definisi universal engagement. Kalau penelitian sebenarnya, Anda harus menjelaskan mengapa reply, repost, dan like dijumlahkan dan apakah bobotnya memang seharusnya sama.&lt;br /&gt;
&lt;br /&gt;
===Buat jumlah kata===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;word_count&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Buat variabel tanggal dan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaning = memperbaiki data.&lt;br /&gt;
Preprocessing = membuat data menjadi lebih siap untuk analisis.&lt;br /&gt;
&lt;br /&gt;
===Validasi===&lt;br /&gt;
Jumlah data:&lt;br /&gt;
 len(df)&lt;br /&gt;
&lt;br /&gt;
Missing value:&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Duplicate:&lt;br /&gt;
 df.duplicated(subset=&amp;quot;uri&amp;quot;).sum()&lt;br /&gt;
&lt;br /&gt;
Statistik engagement:&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
Tampilkan hasil:&lt;br /&gt;
 df.head()&lt;br /&gt;
&lt;br /&gt;
Kode berhasil dijalankan belum berarti data sudah benar. Kita tetap harus memeriksa hasil.&lt;br /&gt;
&lt;br /&gt;
===Simpan===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Kode lengkap==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 1. LOAD DATA&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. DUPLICATE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. MISSING DISPLAY NAME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. DATE / TIME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 5. LANGUAGE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 6. NUMERIC VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 7. INFORMATION FROM ORIGINAL TEXT&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 8. TEXT CLEANING&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove URL&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove mentions&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Keep hashtag word, remove #&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Lowercase&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove extra whitespace&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 9. DERIVED VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 10. VALIDATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Jumlah data:&amp;quot;, len(df))&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nMissing value:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df.isna().sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nDuplicate URI:&amp;quot;,&lt;br /&gt;
    df.duplicated(&lt;br /&gt;
        subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
    ).sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nStatistik engagement:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 11. SAVE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nData bersih berhasil disimpan.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analisis yang bisa dilakukan==&lt;br /&gt;
===Seberapa tinggi engagement?===&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Posting dengan engagement tertinggi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
top10 = (&lt;br /&gt;
    df.sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;,&lt;br /&gt;
        ascending=False&lt;br /&gt;
    )&lt;br /&gt;
    [&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;username&amp;quot;,&lt;br /&gt;
            &amp;quot;text_clean&amp;quot;,&lt;br /&gt;
            &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
            &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
            &amp;quot;like_count&amp;quot;,&lt;br /&gt;
            &amp;quot;engagement&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
    .head(10)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi Top 10 Engagement===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
top10_plot = (&lt;br /&gt;
    df.nlargest(&lt;br /&gt;
        10,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10_plot.plot(&lt;br /&gt;
    x=&amp;quot;username&amp;quot;,&lt;br /&gt;
    y=&amp;quot;engagement&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;10 Posting dengan Engagement Tertinggi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Engagement&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Akun&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Akun paling aktif===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    &amp;quot;username&amp;quot;&lt;br /&gt;
].value_counts().head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aktivitas berdasarkan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam = (&lt;br /&gt;
    df[&amp;quot;hour&amp;quot;]&lt;br /&gt;
    .value_counts()&lt;br /&gt;
    .sort_index()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
posting_per_jam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visualisasi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam.plot(&lt;br /&gt;
    kind=&amp;quot;bar&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Jumlah Posting per Jam&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Jam (WIB)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Jumlah Posting&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kata yang sering muncul===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import Counter&lt;br /&gt;
&lt;br /&gt;
semua_teks = &amp;quot; &amp;quot;.join(&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kata = re.findall(&lt;br /&gt;
    r&amp;quot;[a-zA-Z][a-zA-Z'-]+&amp;quot;,&lt;br /&gt;
    semua_teks&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
stopwords = {&lt;br /&gt;
    &amp;quot;the&amp;quot;, &amp;quot;and&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;of&amp;quot;,&lt;br /&gt;
    &amp;quot;a&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;for&amp;quot;,&lt;br /&gt;
    &amp;quot;that&amp;quot;, &amp;quot;it&amp;quot;, &amp;quot;on&amp;quot;, &amp;quot;with&amp;quot;,&lt;br /&gt;
    &amp;quot;are&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;as&amp;quot;, &amp;quot;this&amp;quot;,&lt;br /&gt;
    &amp;quot;we&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;they&amp;quot;,&lt;br /&gt;
    &amp;quot;have&amp;quot;, &amp;quot;has&amp;quot;, &amp;quot;was&amp;quot;,&lt;br /&gt;
    &amp;quot;were&amp;quot;, &amp;quot;not&amp;quot;, &amp;quot;but&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    # kata pencarian&lt;br /&gt;
    &amp;quot;climate&amp;quot;,&lt;br /&gt;
    &amp;quot;change&amp;quot;,&lt;br /&gt;
    &amp;quot;climatechange&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kata_bersih = [&lt;br /&gt;
    k&lt;br /&gt;
    for k in kata&lt;br /&gt;
    if k not in stopwords&lt;br /&gt;
    and len(k) &amp;gt; 2&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
frekuensi = Counter(&lt;br /&gt;
    kata_bersih&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
frekuensi.most_common(20)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi 15 kata teratas===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
freq_df = pd.DataFrame(&lt;br /&gt;
    frekuensi.most_common(15),&lt;br /&gt;
    columns=[&lt;br /&gt;
        &amp;quot;word&amp;quot;,&lt;br /&gt;
        &amp;quot;frequency&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df = freq_df.sort_values(&lt;br /&gt;
    &amp;quot;frequency&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df.plot(&lt;br /&gt;
    x=&amp;quot;word&amp;quot;,&lt;br /&gt;
    y=&amp;quot;frequency&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;15 Kata yang Sering Muncul&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Frekuensi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Kata&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=416</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=416"/>
		<updated>2026-09-30T04:30:50Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* =Rapihkan kolom bahasa */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
==Data Cleaning==&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;br /&gt;
&lt;br /&gt;
Cek nama variabel&lt;br /&gt;
 df.columns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cek kondisi data===&lt;br /&gt;
 df.info()&lt;br /&gt;
 df.head()&lt;br /&gt;
 df.sample(5)&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Untuk kasus saya, ada 15 posting tidak mempunyai display_name, namun kita cek pakah masih memiliki username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek lagi&lt;br /&gt;
 df[&amp;quot;display_name&amp;quot;].isna().sum()&lt;br /&gt;
&lt;br /&gt;
Harus menghasilkan 0&lt;br /&gt;
&lt;br /&gt;
Berarti dalam kasus ini display_name tidak terlalu penting karena masih ada username.&lt;br /&gt;
&lt;br /&gt;
===Cek apakah ada duplicate===&lt;br /&gt;
 df.duplicated().sum()&lt;br /&gt;
&lt;br /&gt;
Klo pada kasus saya, id unik nya adalah uri,jadi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.duplicated(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
).sum()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kode cleaning nya adalah&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kalau satu posting masuk dua kali, analisis kita dapat menghitung satu opini atau satu engagement dua kali.&lt;br /&gt;
&lt;br /&gt;
===Rapihkan display_name===&lt;br /&gt;
Beberapa nama mungkin memiliki spasi tambahan.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita rapihkan juga username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perbaiki type tanggal===&lt;br /&gt;
Kita cek tipe datanya&lt;br /&gt;
 df[&amp;quot;created_at&amp;quot;].dtype&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya = object, berarti masih dianggap teks, jadi harus diubah ke tipe waktu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah UTC ke waktu Jakarta===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&amp;quot;created_at&amp;quot;, &amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rapihkan kolom bahasa===&lt;br /&gt;
 df[&amp;quot;language&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
Perbaiki&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;language_primary&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Pastikan reply, repost dan like benar-benar numerik===&lt;br /&gt;
Cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].dtypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jika masih belum angka&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jika ada URL terambil===&lt;br /&gt;
Buat variabel, barangkali nanti url tersebut dibutuhkan&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_url&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Deteksi Hastag===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_hashtag&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
==Preprocessing==&lt;br /&gt;
===Buat Clean Text===&lt;br /&gt;
Kita mulai masuk ke preprocessing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hapus URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nanti hasilnya misal: &amp;lt;b&amp;gt;Climate change is real https://example.com&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Climate change is real&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Hilangkan mention==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namun mention tidak selalu harus dibuang. Kalau kita ingin melakukan network analysis, mention justru merupakan data yang penting.&lt;br /&gt;
&lt;br /&gt;
===Hastag===&lt;br /&gt;
Jangan buang katanya, namun tanda &amp;quot;#&amp;quot; saja&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah menjadi lowercase===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ini penting agar komputer tidak menganggap kata yang sama namun misal ada huruf kapital, sebagai kata berbeda.&lt;br /&gt;
&lt;br /&gt;
===Rapikan line break dan spasi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bandingkan sebelum dan sesudah===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;text&amp;quot;,&lt;br /&gt;
        &amp;quot;text_clean&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Buat variabel engagement===&lt;br /&gt;
Misal kita perlu untuk menghitung hubungannya.&lt;br /&gt;
Kita definisikan secara sederhana:Engagement = Reply + Repost + Like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ini adalah definisi operasional untuk latihan, bukan definisi universal engagement. Kalau penelitian sebenarnya, Anda harus menjelaskan mengapa reply, repost, dan like dijumlahkan dan apakah bobotnya memang seharusnya sama.&lt;br /&gt;
&lt;br /&gt;
===Buat jumlah kata===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;word_count&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Buat variabel tanggal dan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaning = memperbaiki data.&lt;br /&gt;
Preprocessing = membuat data menjadi lebih siap untuk analisis.&lt;br /&gt;
&lt;br /&gt;
===Validasi===&lt;br /&gt;
Jumlah data:&lt;br /&gt;
 len(df)&lt;br /&gt;
&lt;br /&gt;
Missing value:&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Duplicate:&lt;br /&gt;
 df.duplicated(subset=&amp;quot;uri&amp;quot;).sum()&lt;br /&gt;
&lt;br /&gt;
Statistik engagement:&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
Tampilkan hasil:&lt;br /&gt;
 df.head()&lt;br /&gt;
&lt;br /&gt;
Kode berhasil dijalankan belum berarti data sudah benar. Kita tetap harus memeriksa hasil.&lt;br /&gt;
&lt;br /&gt;
===Simpan===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Kode lengkap==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 1. LOAD DATA&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. DUPLICATE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. MISSING DISPLAY NAME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. DATE / TIME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 5. LANGUAGE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 6. NUMERIC VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 7. INFORMATION FROM ORIGINAL TEXT&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 8. TEXT CLEANING&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove URL&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove mentions&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Keep hashtag word, remove #&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Lowercase&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove extra whitespace&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 9. DERIVED VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 10. VALIDATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Jumlah data:&amp;quot;, len(df))&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nMissing value:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df.isna().sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nDuplicate URI:&amp;quot;,&lt;br /&gt;
    df.duplicated(&lt;br /&gt;
        subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
    ).sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nStatistik engagement:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 11. SAVE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nData bersih berhasil disimpan.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analisis yang bisa dilakukan==&lt;br /&gt;
===Seberapa tinggi engagement?===&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Posting dengan engagement tertinggi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
top10 = (&lt;br /&gt;
    df.sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;,&lt;br /&gt;
        ascending=False&lt;br /&gt;
    )&lt;br /&gt;
    [&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;username&amp;quot;,&lt;br /&gt;
            &amp;quot;text_clean&amp;quot;,&lt;br /&gt;
            &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
            &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
            &amp;quot;like_count&amp;quot;,&lt;br /&gt;
            &amp;quot;engagement&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
    .head(10)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi Top 10 Engagement===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
top10_plot = (&lt;br /&gt;
    df.nlargest(&lt;br /&gt;
        10,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10_plot.plot(&lt;br /&gt;
    x=&amp;quot;username&amp;quot;,&lt;br /&gt;
    y=&amp;quot;engagement&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;10 Posting dengan Engagement Tertinggi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Engagement&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Akun&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Akun paling aktif===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    &amp;quot;username&amp;quot;&lt;br /&gt;
].value_counts().head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aktivitas berdasarkan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam = (&lt;br /&gt;
    df[&amp;quot;hour&amp;quot;]&lt;br /&gt;
    .value_counts()&lt;br /&gt;
    .sort_index()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
posting_per_jam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visualisasi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam.plot(&lt;br /&gt;
    kind=&amp;quot;bar&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Jumlah Posting per Jam&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Jam (WIB)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Jumlah Posting&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kata yang sering muncul===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import Counter&lt;br /&gt;
&lt;br /&gt;
semua_teks = &amp;quot; &amp;quot;.join(&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kata = re.findall(&lt;br /&gt;
    r&amp;quot;[a-zA-Z][a-zA-Z'-]+&amp;quot;,&lt;br /&gt;
    semua_teks&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
stopwords = {&lt;br /&gt;
    &amp;quot;the&amp;quot;, &amp;quot;and&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;of&amp;quot;,&lt;br /&gt;
    &amp;quot;a&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;for&amp;quot;,&lt;br /&gt;
    &amp;quot;that&amp;quot;, &amp;quot;it&amp;quot;, &amp;quot;on&amp;quot;, &amp;quot;with&amp;quot;,&lt;br /&gt;
    &amp;quot;are&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;as&amp;quot;, &amp;quot;this&amp;quot;,&lt;br /&gt;
    &amp;quot;we&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;they&amp;quot;,&lt;br /&gt;
    &amp;quot;have&amp;quot;, &amp;quot;has&amp;quot;, &amp;quot;was&amp;quot;,&lt;br /&gt;
    &amp;quot;were&amp;quot;, &amp;quot;not&amp;quot;, &amp;quot;but&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    # kata pencarian&lt;br /&gt;
    &amp;quot;climate&amp;quot;,&lt;br /&gt;
    &amp;quot;change&amp;quot;,&lt;br /&gt;
    &amp;quot;climatechange&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kata_bersih = [&lt;br /&gt;
    k&lt;br /&gt;
    for k in kata&lt;br /&gt;
    if k not in stopwords&lt;br /&gt;
    and len(k) &amp;gt; 2&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
frekuensi = Counter(&lt;br /&gt;
    kata_bersih&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
frekuensi.most_common(20)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi 15 kata teratas===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
freq_df = pd.DataFrame(&lt;br /&gt;
    frekuensi.most_common(15),&lt;br /&gt;
    columns=[&lt;br /&gt;
        &amp;quot;word&amp;quot;,&lt;br /&gt;
        &amp;quot;frequency&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df = freq_df.sort_values(&lt;br /&gt;
    &amp;quot;frequency&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df.plot(&lt;br /&gt;
    x=&amp;quot;word&amp;quot;,&lt;br /&gt;
    y=&amp;quot;frequency&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;15 Kata yang Sering Muncul&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Frekuensi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Kata&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=415</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=415"/>
		<updated>2026-09-30T04:30:25Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
==Data Cleaning==&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;br /&gt;
&lt;br /&gt;
Cek nama variabel&lt;br /&gt;
 df.columns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cek kondisi data===&lt;br /&gt;
 df.info()&lt;br /&gt;
 df.head()&lt;br /&gt;
 df.sample(5)&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Untuk kasus saya, ada 15 posting tidak mempunyai display_name, namun kita cek pakah masih memiliki username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek lagi&lt;br /&gt;
 df[&amp;quot;display_name&amp;quot;].isna().sum()&lt;br /&gt;
&lt;br /&gt;
Harus menghasilkan 0&lt;br /&gt;
&lt;br /&gt;
Berarti dalam kasus ini display_name tidak terlalu penting karena masih ada username.&lt;br /&gt;
&lt;br /&gt;
===Cek apakah ada duplicate===&lt;br /&gt;
 df.duplicated().sum()&lt;br /&gt;
&lt;br /&gt;
Klo pada kasus saya, id unik nya adalah uri,jadi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.duplicated(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
).sum()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kode cleaning nya adalah&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kalau satu posting masuk dua kali, analisis kita dapat menghitung satu opini atau satu engagement dua kali.&lt;br /&gt;
&lt;br /&gt;
===Rapihkan display_name===&lt;br /&gt;
Beberapa nama mungkin memiliki spasi tambahan.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita rapihkan juga username&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perbaiki type tanggal===&lt;br /&gt;
Kita cek tipe datanya&lt;br /&gt;
 df[&amp;quot;created_at&amp;quot;].dtype&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya = object, berarti masih dianggap teks, jadi harus diubah ke tipe waktu.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah UTC ke waktu Jakarta===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kemudian cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&amp;quot;created_at&amp;quot;, &amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rapihkan kolom bahasa==&lt;br /&gt;
 df[&amp;quot;language&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
Perbaiki&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;language_primary&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Pastikan reply, repost dan like benar-benar numerik===&lt;br /&gt;
Cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].dtypes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jika masih belum angka&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Jika ada URL terambil===&lt;br /&gt;
Buat variabel, barangkali nanti url tersebut dibutuhkan&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_url&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
===Deteksi Hastag===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;has_hashtag&amp;quot;].value_counts()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Preprocessing==&lt;br /&gt;
===Buat Clean Text===&lt;br /&gt;
Kita mulai masuk ke preprocessing&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hapus URL&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nanti hasilnya misal: &amp;lt;b&amp;gt;Climate change is real https://example.com&amp;lt;/b&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;Climate change is real&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Hilangkan mention==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Namun mention tidak selalu harus dibuang. Kalau kita ingin melakukan network analysis, mention justru merupakan data yang penting.&lt;br /&gt;
&lt;br /&gt;
===Hastag===&lt;br /&gt;
Jangan buang katanya, namun tanda &amp;quot;#&amp;quot; saja&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Ubah menjadi lowercase===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ini penting agar komputer tidak menganggap kata yang sama namun misal ada huruf kapital, sebagai kata berbeda.&lt;br /&gt;
&lt;br /&gt;
===Rapikan line break dan spasi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Bandingkan sebelum dan sesudah===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;text&amp;quot;,&lt;br /&gt;
        &amp;quot;text_clean&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Buat variabel engagement===&lt;br /&gt;
Misal kita perlu untuk menghitung hubungannya.&lt;br /&gt;
Kita definisikan secara sederhana:Engagement = Reply + Repost + Like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kita cek&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
        &amp;quot;like_count&amp;quot;,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
].head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ini adalah definisi operasional untuk latihan, bukan definisi universal engagement. Kalau penelitian sebenarnya, Anda harus menjelaskan mengapa reply, repost, dan like dijumlahkan dan apakah bobotnya memang seharusnya sama.&lt;br /&gt;
&lt;br /&gt;
===Buat jumlah kata===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek&lt;br /&gt;
 df[&amp;quot;word_count&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Buat variabel tanggal dan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cleaning = memperbaiki data.&lt;br /&gt;
Preprocessing = membuat data menjadi lebih siap untuk analisis.&lt;br /&gt;
&lt;br /&gt;
===Validasi===&lt;br /&gt;
Jumlah data:&lt;br /&gt;
 len(df)&lt;br /&gt;
&lt;br /&gt;
Missing value:&lt;br /&gt;
 df.isna().sum()&lt;br /&gt;
&lt;br /&gt;
Duplicate:&lt;br /&gt;
 df.duplicated(subset=&amp;quot;uri&amp;quot;).sum()&lt;br /&gt;
&lt;br /&gt;
Statistik engagement:&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
Tampilkan hasil:&lt;br /&gt;
 df.head()&lt;br /&gt;
&lt;br /&gt;
Kode berhasil dijalankan belum berarti data sudah benar. Kita tetap harus memeriksa hasil.&lt;br /&gt;
&lt;br /&gt;
===Simpan===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Kode lengkap==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 1. LOAD DATA&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. DUPLICATE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df = df.drop_duplicates(&lt;br /&gt;
    subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. MISSING DISPLAY NAME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;display_name&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;display_name&amp;quot;]&lt;br /&gt;
    .fillna(df[&amp;quot;username&amp;quot;])&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;username&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;username&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.strip()&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. DATE / TIME&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;],&lt;br /&gt;
    format=&amp;quot;mixed&amp;quot;,&lt;br /&gt;
    utc=True,&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;created_at_wib&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at&amp;quot;]&lt;br /&gt;
    .dt.tz_convert(&amp;quot;Asia/Jakarta&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 5. LANGUAGE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;language_primary&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;language&amp;quot;]&lt;br /&gt;
    .astype(str)&lt;br /&gt;
    .str.extract(&lt;br /&gt;
        r&amp;quot;([A-Za-z]+(?:-[A-Za-z]+)?)&amp;quot;,&lt;br /&gt;
        expand=False&lt;br /&gt;
    )&lt;br /&gt;
    .fillna(&amp;quot;unknown&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 6. NUMERIC VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
kolom_angka = [&lt;br /&gt;
    &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
    &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
    &amp;quot;like_count&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
for kolom in kolom_angka:&lt;br /&gt;
&lt;br /&gt;
    df[kolom] = pd.to_numeric(&lt;br /&gt;
        df[kolom],&lt;br /&gt;
        errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
    ).fillna(0).astype(int)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 7. INFORMATION FROM ORIGINAL TEXT&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_url&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;https?://|www\.&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;has_hashtag&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .str.contains(&lt;br /&gt;
        r&amp;quot;#\w+&amp;quot;,&lt;br /&gt;
        regex=True,&lt;br /&gt;
        na=False&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 8. TEXT CLEANING&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text&amp;quot;]&lt;br /&gt;
    .fillna(&amp;quot;&amp;quot;)&lt;br /&gt;
    .astype(str)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove URL&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;https?://\S+|www\.\S+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove mentions&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;@[\w.-]+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Keep hashtag word, remove #&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;#(\w+)&amp;quot;,&lt;br /&gt;
        r&amp;quot;\1&amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Lowercase&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.lower()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove extra whitespace&lt;br /&gt;
df[&amp;quot;text_clean&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.replace(&lt;br /&gt;
        r&amp;quot;\s+&amp;quot;,&lt;br /&gt;
        &amp;quot; &amp;quot;,&lt;br /&gt;
        regex=True&lt;br /&gt;
    )&lt;br /&gt;
    .str.strip()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 9. DERIVED VARIABLES&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;engagement&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;reply_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;repost_count&amp;quot;]&lt;br /&gt;
    + df[&amp;quot;like_count&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;word_count&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
    .str.findall(&lt;br /&gt;
        r&amp;quot;\b[\w’'-]+\b&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .str.len()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;date&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.date&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;hour&amp;quot;] = (&lt;br /&gt;
    df[&amp;quot;created_at_wib&amp;quot;]&lt;br /&gt;
    .dt.hour&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 10. VALIDATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Jumlah data:&amp;quot;, len(df))&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nMissing value:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df.isna().sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nDuplicate URI:&amp;quot;,&lt;br /&gt;
    df.duplicated(&lt;br /&gt;
        subset=&amp;quot;uri&amp;quot;&lt;br /&gt;
    ).sum()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nStatistik engagement:&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 11. SAVE&lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_clean.csv&amp;quot;,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nData bersih berhasil disimpan.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analisis yang bisa dilakukan==&lt;br /&gt;
===Seberapa tinggi engagement?===&lt;br /&gt;
 df[&amp;quot;engagement&amp;quot;].describe()&lt;br /&gt;
&lt;br /&gt;
===Posting dengan engagement tertinggi===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
top10 = (&lt;br /&gt;
    df.sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;,&lt;br /&gt;
        ascending=False&lt;br /&gt;
    )&lt;br /&gt;
    [&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;username&amp;quot;,&lt;br /&gt;
            &amp;quot;text_clean&amp;quot;,&lt;br /&gt;
            &amp;quot;reply_count&amp;quot;,&lt;br /&gt;
            &amp;quot;repost_count&amp;quot;,&lt;br /&gt;
            &amp;quot;like_count&amp;quot;,&lt;br /&gt;
            &amp;quot;engagement&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
    .head(10)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi Top 10 Engagement===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
top10_plot = (&lt;br /&gt;
    df.nlargest(&lt;br /&gt;
        10,&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    .sort_values(&lt;br /&gt;
        &amp;quot;engagement&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
top10_plot.plot(&lt;br /&gt;
    x=&amp;quot;username&amp;quot;,&lt;br /&gt;
    y=&amp;quot;engagement&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;10 Posting dengan Engagement Tertinggi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Engagement&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Akun&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Akun paling aktif===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
df[&lt;br /&gt;
    &amp;quot;username&amp;quot;&lt;br /&gt;
].value_counts().head(10)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Aktivitas berdasarkan jam===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam = (&lt;br /&gt;
    df[&amp;quot;hour&amp;quot;]&lt;br /&gt;
    .value_counts()&lt;br /&gt;
    .sort_index()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
posting_per_jam&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Visualisasi&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
posting_per_jam.plot(&lt;br /&gt;
    kind=&amp;quot;bar&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Jumlah Posting per Jam&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Jam (WIB)&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Jumlah Posting&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Kata yang sering muncul===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from collections import Counter&lt;br /&gt;
&lt;br /&gt;
semua_teks = &amp;quot; &amp;quot;.join(&lt;br /&gt;
    df[&amp;quot;text_clean&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kata = re.findall(&lt;br /&gt;
    r&amp;quot;[a-zA-Z][a-zA-Z'-]+&amp;quot;,&lt;br /&gt;
    semua_teks&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
stopwords = {&lt;br /&gt;
    &amp;quot;the&amp;quot;, &amp;quot;and&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;of&amp;quot;,&lt;br /&gt;
    &amp;quot;a&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;is&amp;quot;, &amp;quot;for&amp;quot;,&lt;br /&gt;
    &amp;quot;that&amp;quot;, &amp;quot;it&amp;quot;, &amp;quot;on&amp;quot;, &amp;quot;with&amp;quot;,&lt;br /&gt;
    &amp;quot;are&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;as&amp;quot;, &amp;quot;this&amp;quot;,&lt;br /&gt;
    &amp;quot;we&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;you&amp;quot;, &amp;quot;they&amp;quot;,&lt;br /&gt;
    &amp;quot;have&amp;quot;, &amp;quot;has&amp;quot;, &amp;quot;was&amp;quot;,&lt;br /&gt;
    &amp;quot;were&amp;quot;, &amp;quot;not&amp;quot;, &amp;quot;but&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
    # kata pencarian&lt;br /&gt;
    &amp;quot;climate&amp;quot;,&lt;br /&gt;
    &amp;quot;change&amp;quot;,&lt;br /&gt;
    &amp;quot;climatechange&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
kata_bersih = [&lt;br /&gt;
    k&lt;br /&gt;
    for k in kata&lt;br /&gt;
    if k not in stopwords&lt;br /&gt;
    and len(k) &amp;gt; 2&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
frekuensi = Counter(&lt;br /&gt;
    kata_bersih&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
frekuensi.most_common(20)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visualisasi 15 kata teratas===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
freq_df = pd.DataFrame(&lt;br /&gt;
    frekuensi.most_common(15),&lt;br /&gt;
    columns=[&lt;br /&gt;
        &amp;quot;word&amp;quot;,&lt;br /&gt;
        &amp;quot;frequency&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df = freq_df.sort_values(&lt;br /&gt;
    &amp;quot;frequency&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
freq_df.plot(&lt;br /&gt;
    x=&amp;quot;word&amp;quot;,&lt;br /&gt;
    y=&amp;quot;frequency&amp;quot;,&lt;br /&gt;
    kind=&amp;quot;barh&amp;quot;,&lt;br /&gt;
    legend=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;15 Kata yang Sering Muncul&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&lt;br /&gt;
    &amp;quot;Frekuensi&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.ylabel(&lt;br /&gt;
    &amp;quot;Kata&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=414</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=414"/>
		<updated>2026-09-30T03:58:15Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cek ukuran data&lt;br /&gt;
 df.shape&lt;br /&gt;
&lt;br /&gt;
Klo di contoh saya nanti hasilnya adalah (97, 9). Artinya: 97 baris × 9 variabel.&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=413</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=413"/>
		<updated>2026-09-30T03:57:02Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
===Import library dan membaca data===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=412</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=412"/>
		<updated>2026-09-30T03:56:17Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Replaced content with &amp;quot;Dari contoh yang didapat, kita akan melakukan hal berikut  &amp;lt;pre&amp;gt; bluesky_climate_change_raw.csv             ↓       DATA CLEANING             ↓       PREPROCESSING...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dari contoh yang didapat, kita akan melakukan hal berikut&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
            ↓&lt;br /&gt;
      DATA CLEANING&lt;br /&gt;
            ↓&lt;br /&gt;
      PREPROCESSING&lt;br /&gt;
            ↓&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
            ↓&lt;br /&gt;
        ANALISIS&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step by step nya adalah&lt;br /&gt;
&lt;br /&gt;
### Import library dan membaca data&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df.head()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=411</id>
		<title>Pengambilan-data-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=411"/>
		<updated>2026-09-30T03:47:43Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 1. Folder project&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 2. API&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
url = (&lt;br /&gt;
    &amp;quot;https://api.bsky.app/&amp;quot;&lt;br /&gt;
    &amp;quot;xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 3. Request&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;:&lt;br /&gt;
            &amp;quot;application/json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;:&lt;br /&gt;
            &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 4. Validasi response&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        f&amp;quot;HTTP {response.status_code}: &amp;quot;&lt;br /&gt;
        f&amp;quot;{response.text[:300]}&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
data = response.json()&lt;br /&gt;
&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 5. Simpan JSON asli&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 6. Ubah ke tabel&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 7. Simpan CSV raw&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 8. Pemeriksaan&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Ukuran dataset:&amp;quot;,&lt;br /&gt;
    df_raw.shape&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
display(&lt;br /&gt;
    df_raw.head()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;PROJECT = Path(&amp;quot;/media/Kuliah/BigDataFisip&amp;quot;)&amp;lt;/b&amp;gt; sesuaikan saja dengan PATH yang kalian miliki.&lt;br /&gt;
&lt;br /&gt;
Pada bagian &amp;lt;b&amp;gt;&amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&amp;lt;/b&amp;gt; sesuaikan saja tentang topik apa yang dicari.&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=410</id>
		<title>Pengambilan-data-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Pengambilan-data-fisip&amp;diff=410"/>
		<updated>2026-09-30T03:44:36Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;&amp;lt;pre&amp;gt; import json import requests import pandas as pd  from pathlib import Path   # ======================================== # 1. Folder project # ============================...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 1. Folder project&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/bgoode/Data4/Unpad/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 2. API&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
url = (&lt;br /&gt;
    &amp;quot;https://api.bsky.app/&amp;quot;&lt;br /&gt;
    &amp;quot;xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 3. Request&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;:&lt;br /&gt;
            &amp;quot;application/json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;:&lt;br /&gt;
            &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 4. Validasi response&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        f&amp;quot;HTTP {response.status_code}: &amp;quot;&lt;br /&gt;
        f&amp;quot;{response.text[:300]}&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
data = response.json()&lt;br /&gt;
&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 5. Simpan JSON asli&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 6. Ubah ke tabel&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 7. Simpan CSV raw&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 8. Pemeriksaan&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Ukuran dataset:&amp;quot;,&lt;br /&gt;
    df_raw.shape&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
display(&lt;br /&gt;
    df_raw.head()&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=409</id>
		<title>Big Data Fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=409"/>
		<updated>2026-09-30T03:43:27Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Berikut ini adalah beberapa kode yang dapat digunakan untuk praktek pengambilan data dan cleaning data&lt;br /&gt;
&lt;br /&gt;
* [[Pengambilan-data-fisip]]&lt;br /&gt;
* [[Data-cleaning-fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=408</id>
		<title>Big Data Fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=408"/>
		<updated>2026-09-30T03:43:12Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Berikut ini adalah beberapa kode yang dapat digunakan untuk praktek pengambilan data dan cleaning data&lt;br /&gt;
&lt;br /&gt;
[[Pengambilan-data-fisip]]&lt;br /&gt;
[[Data-cleaning-fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=407</id>
		<title>Big Data Fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Big_Data_Fisip&amp;diff=407"/>
		<updated>2026-09-30T03:42:08Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;Berikut ini adalah beberapa kode yang dapat digunakan untuk praktek pengambilan data dan cleaning data  Data-cleaning-fisip&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Berikut ini adalah beberapa kode yang dapat digunakan untuk praktek pengambilan data dan cleaning data&lt;br /&gt;
&lt;br /&gt;
[[Data-cleaning-fisip]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=406</id>
		<title>Data-cleaning-fisip</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Data-cleaning-fisip&amp;diff=406"/>
		<updated>2026-09-16T05:06:27Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;Ada dua bentuk data mentah:  1. `JSON` → salinan respons API, sedekat mungkin dengan data asli dari Bluesky. 2. `CSV` → field penting sudah dijadikan tabel, tetapi **belum...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ada dua bentuk data mentah:&lt;br /&gt;
&lt;br /&gt;
1. `JSON` → salinan respons API, sedekat mungkin dengan data asli dari Bluesky.&lt;br /&gt;
2. `CSV` → field penting sudah dijadikan tabel, tetapi **belum dibersihkan** sehingga cocok untuk latihan mahasiswa.&lt;br /&gt;
&lt;br /&gt;
Secara resmi, `app.bsky.feed.searchPosts` mewajibkan parameter `q`, mendukung `sort=latest/top`, filter `lang`, dan `limit` maksimum **100** per request. Dokumentasi juga mengingatkan bahwa sintaks pencarian frasa/Boolean tidak sepenuhnya dispesifikasikan, walaupun sintaks Lucene direkomendasikan. &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# A. Target akhir praktikum&lt;br /&gt;
&lt;br /&gt;
Kita akan menghasilkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
BigDataFisip/&lt;br /&gt;
│&lt;br /&gt;
├── venvs/&lt;br /&gt;
│   └── jupyter-polsci/&lt;br /&gt;
│&lt;br /&gt;
└── data/&lt;br /&gt;
    ├── raw/&lt;br /&gt;
    │   ├── bluesky_climate_change_raw.json&lt;br /&gt;
    │   └── bluesky_climate_change_raw.csv&lt;br /&gt;
    │&lt;br /&gt;
    └── processed/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Mahasiswa nantinya **tidak mengubah file di `raw/`**.&lt;br /&gt;
&lt;br /&gt;
Hasil cleaning disimpan ke:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
data/processed/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# B. Langkah 1 — Pastikan Jupyter menggunakan environment yang benar&lt;br /&gt;
&lt;br /&gt;
Buat cell:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
print(sys.executable)&lt;br /&gt;
print(sys.version)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pada komputer seharusnya kurang lebih:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/venvs/jupyter-polsci/bin/python&lt;br /&gt;
&lt;br /&gt;
3.10.12 ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kalau demikian, environment sudah benar.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# C. Langkah 2 — Import library&lt;br /&gt;
&lt;br /&gt;
Buat cell baru:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kita menggunakan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
requests  → mengambil data API&lt;br /&gt;
json      → menyimpan respons asli&lt;br /&gt;
pandas    → mengubah data menjadi tabel&lt;br /&gt;
Path      → mengatur folder/file&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# D. Langkah 3 — Tentukan folder penyimpanan&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/bgoode/Data4/Unpad/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
PROCESSED_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;processed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
PROCESSED_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(RAW_DIR)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
/data/raw&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# E. Langkah 4 — Tentukan topik (misalnya Climate Change)&lt;br /&gt;
&lt;br /&gt;
Endpoint:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
url = &amp;quot;https://api.bsky.app/xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian query:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Artinya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
q&lt;br /&gt;
↓&lt;br /&gt;
mencari &amp;quot;climate change&amp;quot;&lt;br /&gt;
&lt;br /&gt;
limit&lt;br /&gt;
↓&lt;br /&gt;
maksimal 100 posting&lt;br /&gt;
&lt;br /&gt;
sort&lt;br /&gt;
↓&lt;br /&gt;
latest = hasil terbaru&lt;br /&gt;
&lt;br /&gt;
lang&lt;br /&gt;
↓&lt;br /&gt;
en = bahasa Inggris&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Nilai `100` adalah batas maksimum `limit` menurut Lexicon resmi Bluesky. &lt;br /&gt;
&lt;br /&gt;
Catatan:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; `limit=100` berarti **meminta maksimal 100**, bukan jaminan server selalu memberikan tepat 100.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# F. Langkah 5 — Kirim request&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;: &amp;quot;application/json&amp;quot;,&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;: &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Content-Type:&amp;quot;,&lt;br /&gt;
    response.headers.get(&amp;quot;content-type&amp;quot;)&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Harapannya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
HTTP Status: 200&lt;br /&gt;
Content-Type: application/json; charset=utf-8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# G. Langkah 6 — Cek hasil JSON&lt;br /&gt;
&lt;br /&gt;
Gunakan:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    print(&amp;quot;Request gagal&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    print(&lt;br /&gt;
        response.text[:1000]&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        &amp;quot;Data belum berhasil diambil&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian pastikan hasil memang JSON:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
content_type = response.headers.get(&lt;br /&gt;
    &amp;quot;content-type&amp;quot;,&lt;br /&gt;
    &amp;quot;&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
if &amp;quot;application/json&amp;quot; not in content_type:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        &amp;quot;Respons server bukan JSON&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Baru setelah itu:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
data = response.json()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Ini mencegah error:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
JSONDecodeError&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
ketika server sebenarnya memberikan HTML error.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# H. Langkah 7 — Ambil daftar posting&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Target:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Jumlah posting: 100&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Jika hasilnya misalnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Jumlah posting: 86&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
jangan mengubahnya menjadi 100, biarkan saja.&lt;br /&gt;
&lt;br /&gt;
Itu berarti API memang hanya mengembalikan 86 pada request tersebut.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# I. Langkah 8 — Lihat bentuk JSON&lt;br /&gt;
&lt;br /&gt;
Sekarang:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
print(&lt;br /&gt;
    data.keys()&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lalu:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
print(&lt;br /&gt;
    posts[0].keys()&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dan lihat posting pertama:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
posts[0]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Mahasiswa kemungkinan akan melihat struktur yang cukup kompleks.&lt;br /&gt;
&lt;br /&gt;
Secara sederhana:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
post&lt;br /&gt;
│&lt;br /&gt;
├── uri&lt;br /&gt;
├── cid&lt;br /&gt;
│&lt;br /&gt;
├── author&lt;br /&gt;
│   ├── handle&lt;br /&gt;
│   ├── displayName&lt;br /&gt;
│   └── ...&lt;br /&gt;
│&lt;br /&gt;
├── record&lt;br /&gt;
│   ├── text&lt;br /&gt;
│   ├── createdAt&lt;br /&gt;
│   ├── langs&lt;br /&gt;
│   └── ...&lt;br /&gt;
│&lt;br /&gt;
├── replyCount&lt;br /&gt;
├── repostCount&lt;br /&gt;
├── likeCount&lt;br /&gt;
└── ...&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&amp;gt; **Data dari API belum tentu berbentuk tabel seperti Excel.**&lt;br /&gt;
&lt;br /&gt;
Data API sering berbentuk:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
JSON&lt;br /&gt;
    ↓&lt;br /&gt;
nested / bertingkat&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# J. Langkah 9 — Simpan JSON mentah terlebih dahulu&lt;br /&gt;
&lt;br /&gt;
**Lakukan ini sebelum cleaning.**&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Tersimpan:&amp;quot;,&lt;br /&gt;
    json_file&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sekarang kita memiliki:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
data/raw/&lt;br /&gt;
└── bluesky_climate_change_raw.json&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
File ini **jangan diedit**.&lt;br /&gt;
&lt;br /&gt;
Anggap sebagai:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; salinan data asli yang diterima dari API.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# K. Langkah 10 — Pilih field yang akan dipelajari mahasiswa&lt;br /&gt;
&lt;br /&gt;
Sekarang JSON bertingkat kita ubah menjadi tabel.&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# L. Langkah 11 — Lihat hasil tabel&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.head()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kurang lebih mahasiswa akan memperoleh:&lt;br /&gt;
&lt;br /&gt;
| created_at | username | text              | language | reply_count | repost_count | like_count |&lt;br /&gt;
| ---------- | -------- | ----------------- | -------- | ----------: | -----------: | ---------: |&lt;br /&gt;
| ...        | user1    | Climate change... | ['en']   |           1 |            3 |         12 |&lt;br /&gt;
| ...        | user2    | New report...     | ['en']   |           0 |            1 |          6 |&lt;br /&gt;
| ...        | user3    | ...               | ['en']   |           2 |            0 |          9 |&lt;br /&gt;
&lt;br /&gt;
Kemudian:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.shape&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Harapannya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
(100, 9)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# M. Langkah 12 — Periksa kondisi data, tetapi jangan dibersihkan dahulu&lt;br /&gt;
&lt;br /&gt;
Jalankan:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.info()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemudian:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.isna().sum()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Cek juga:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.head(10)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dan:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw[&amp;quot;text&amp;quot;].head(10)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Pada tahap ini mahasiswa hanya **mengamati**.&lt;br /&gt;
&lt;br /&gt;
Belum:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
dropna()&lt;br /&gt;
drop_duplicates()&lt;br /&gt;
replace()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
dan sebagainya.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# N. Langkah 13 — Simpan CSV mentah&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Tersimpan:&amp;quot;,&lt;br /&gt;
    csv_file&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Hasil akhirnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
BigDataFisip/&lt;br /&gt;
└── data/&lt;br /&gt;
    │&lt;br /&gt;
    ├── raw/&lt;br /&gt;
    │   ├── bluesky_climate_change_raw.json&lt;br /&gt;
    │   └── bluesky_climate_change_raw.csv&lt;br /&gt;
    │&lt;br /&gt;
    └── processed/&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Saya menggunakan:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
supaya karakter seperti emoji dan karakter non-ASCII relatif aman jika CSV nantinya dibuka menggunakan Excel.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# O. Perbedaan dua file tersebut&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
### `raw.json`&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Bluesky API&lt;br /&gt;
     ↓&lt;br /&gt;
  JSON asli&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Belum kita ubah strukturnya.&lt;br /&gt;
&lt;br /&gt;
### `raw.csv`&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
JSON&lt;br /&gt;
 ↓&lt;br /&gt;
pilih field&lt;br /&gt;
 ↓&lt;br /&gt;
tabel&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Sudah mengalami **transformasi struktur**, tetapi belum mengalami cleaning isi.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# P. Sekarang mahasiswa mendapatkan dataset untuk cleaning&lt;br /&gt;
&lt;br /&gt;
Setelah raw CSV tersedia, praktik berikutnya bisa dimulai.&lt;br /&gt;
&lt;br /&gt;
### 1. Cek tipe data&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.info()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 2. Cari missing value&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.isna().sum()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Mahasiswa menentukan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
mana yang kosong?&lt;br /&gt;
kenapa bisa kosong?&lt;br /&gt;
perlukah dihapus?&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 3. Periksa duplikasi&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.duplicated().sum()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Lebih baik juga:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw.duplicated(&lt;br /&gt;
    subset=[&amp;quot;uri&amp;quot;]&lt;br /&gt;
).sum()&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Diskusikan:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Mengapa `uri` lebih cocok untuk memeriksa posting yang sama dibandingkan seluruh row?&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 4. Periksa teks&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
display(&lt;br /&gt;
    df_raw[[&amp;quot;text&amp;quot;]]&lt;br /&gt;
    .head(20)&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Kemungkinan ditemukan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
URL&lt;br /&gt;
emoji&lt;br /&gt;
hashtag&lt;br /&gt;
newline&lt;br /&gt;
spasi berlebih&lt;br /&gt;
mention&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Itulah bahan untuk text cleaning.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 5. Periksa relevansi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cari:&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
df_raw[&lt;br /&gt;
    [&amp;quot;text&amp;quot;]&lt;br /&gt;
].head(20)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Tanyakan:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Apakah semuanya benar-benar membahas climate change?&lt;br /&gt;
&lt;br /&gt;
Tidak boleh otomatis diasumsikan iya, karena dokumentasi Bluesky sendiri menyatakan sintaks dan perilaku query tidak sepenuhnya dispesifikasikan. &lt;br /&gt;
&lt;br /&gt;
Ini bisa menjadi contoh nyata:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Search API&lt;br /&gt;
     ↓&lt;br /&gt;
candidate data&lt;br /&gt;
&lt;br /&gt;
bukan&lt;br /&gt;
&lt;br /&gt;
Search API&lt;br /&gt;
     ↓&lt;br /&gt;
ground truth&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# Q. Tugas cleaning &lt;br /&gt;
&lt;br /&gt;
Mahasiswa diminta menghasilkan:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
bluesky_climate_change_clean.csv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
dari:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
bluesky_climate_change_raw.csv&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Dengan tugas:&lt;br /&gt;
&lt;br /&gt;
**1. Konversi tanggal**&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
created_at&lt;br /&gt;
string → datetime&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
**2. Missing value**&lt;br /&gt;
&lt;br /&gt;
Identifikasi dan tentukan perlakuannya.&lt;br /&gt;
&lt;br /&gt;
**3. Duplikasi**&lt;br /&gt;
&lt;br /&gt;
Gunakan `uri` untuk membantu mendeteksi posting yang sama.&lt;br /&gt;
&lt;br /&gt;
**4. Cleaning text**&lt;br /&gt;
&lt;br /&gt;
Misalnya:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
newline&lt;br /&gt;
spasi berlebih&lt;br /&gt;
URL&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Namun mahasiswa harus menjelaskan **mengapa suatu elemen dihapus**, bukan sekadar menghapus semuanya.&lt;br /&gt;
&lt;br /&gt;
**5. Relevansi topik**&lt;br /&gt;
&lt;br /&gt;
Periksa apakah posting benar-benar terkait perubahan iklim.&lt;br /&gt;
&lt;br /&gt;
**6. Engagement**&lt;br /&gt;
&lt;br /&gt;
Buat variabel:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
engagement&lt;br /&gt;
=&lt;br /&gt;
reply_count&lt;br /&gt;
+&lt;br /&gt;
repost_count&lt;br /&gt;
+&lt;br /&gt;
like_count&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
# R. Kode lengkap pengambilan data&lt;br /&gt;
&lt;br /&gt;
```python&lt;br /&gt;
import json&lt;br /&gt;
import requests&lt;br /&gt;
import pandas as pd&lt;br /&gt;
&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 1. Folder project&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
PROJECT = Path(&lt;br /&gt;
    &amp;quot;/media/bgoode/Data4/Unpad/Kuliah/BigDataFisip&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
RAW_DIR = PROJECT / &amp;quot;data&amp;quot; / &amp;quot;raw&amp;quot;&lt;br /&gt;
&lt;br /&gt;
RAW_DIR.mkdir(&lt;br /&gt;
    parents=True,&lt;br /&gt;
    exist_ok=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 2. API&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
url = (&lt;br /&gt;
    &amp;quot;https://api.bsky.app/&amp;quot;&lt;br /&gt;
    &amp;quot;xrpc/app.bsky.feed.searchPosts&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
params = {&lt;br /&gt;
    &amp;quot;q&amp;quot;: '&amp;quot;climate change&amp;quot;',&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;sort&amp;quot;: &amp;quot;latest&amp;quot;,&lt;br /&gt;
    &amp;quot;lang&amp;quot;: &amp;quot;en&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 3. Request&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
response = requests.get(&lt;br /&gt;
    url,&lt;br /&gt;
    params=params,&lt;br /&gt;
    headers={&lt;br /&gt;
        &amp;quot;Accept&amp;quot;:&lt;br /&gt;
            &amp;quot;application/json&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;User-Agent&amp;quot;:&lt;br /&gt;
            &amp;quot;BigDataFisip-Class/1.0&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    timeout=30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;HTTP Status:&amp;quot;,&lt;br /&gt;
    response.status_code&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 4. Validasi response&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
if response.status_code != 200:&lt;br /&gt;
&lt;br /&gt;
    raise RuntimeError(&lt;br /&gt;
        f&amp;quot;HTTP {response.status_code}: &amp;quot;&lt;br /&gt;
        f&amp;quot;{response.text[:300]}&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
data = response.json()&lt;br /&gt;
&lt;br /&gt;
posts = data.get(&lt;br /&gt;
    &amp;quot;posts&amp;quot;,&lt;br /&gt;
    []&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Jumlah posting:&amp;quot;,&lt;br /&gt;
    len(posts)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 5. Simpan JSON asli&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
json_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.json&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
with open(&lt;br /&gt;
    json_file,&lt;br /&gt;
    &amp;quot;w&amp;quot;,&lt;br /&gt;
    encoding=&amp;quot;utf-8&amp;quot;&lt;br /&gt;
) as f:&lt;br /&gt;
&lt;br /&gt;
    json.dump(&lt;br /&gt;
        data,&lt;br /&gt;
        f,&lt;br /&gt;
        ensure_ascii=False,&lt;br /&gt;
        indent=2&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 6. Ubah ke tabel&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
rows = []&lt;br /&gt;
&lt;br /&gt;
for post in posts:&lt;br /&gt;
&lt;br /&gt;
    record = post.get(&lt;br /&gt;
        &amp;quot;record&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    author = post.get(&lt;br /&gt;
        &amp;quot;author&amp;quot;,&lt;br /&gt;
        {}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    rows.append({&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;uri&amp;quot;:&lt;br /&gt;
            post.get(&amp;quot;uri&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;created_at&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;createdAt&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;username&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;handle&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;display_name&amp;quot;:&lt;br /&gt;
            author.get(&amp;quot;displayName&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;text&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;text&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;language&amp;quot;:&lt;br /&gt;
            record.get(&amp;quot;langs&amp;quot;),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;reply_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;replyCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;repost_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;repostCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;like_count&amp;quot;:&lt;br /&gt;
            post.get(&lt;br /&gt;
                &amp;quot;likeCount&amp;quot;,&lt;br /&gt;
                0&lt;br /&gt;
            )&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df_raw = pd.DataFrame(&lt;br /&gt;
    rows&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 7. Simpan CSV raw&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
csv_file = (&lt;br /&gt;
    RAW_DIR /&lt;br /&gt;
    &amp;quot;bluesky_climate_change_raw.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df_raw.to_csv(&lt;br /&gt;
    csv_file,&lt;br /&gt;
    index=False,&lt;br /&gt;
    encoding=&amp;quot;utf-8-sig&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ========================================&lt;br /&gt;
# 8. Pemeriksaan&lt;br /&gt;
# ========================================&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;Ukuran dataset:&amp;quot;,&lt;br /&gt;
    df_raw.shape&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
display(&lt;br /&gt;
    df_raw.head()&lt;br /&gt;
)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
100 data mentah&lt;br /&gt;
       ↓&lt;br /&gt;
identifikasi masalah&lt;br /&gt;
       ↓&lt;br /&gt;
data cleaning&lt;br /&gt;
       ↓&lt;br /&gt;
data processed&lt;br /&gt;
       ↓&lt;br /&gt;
analisis&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
[1]: https://bsky.network/docs/api-directory/?utm_source=chatgpt.com &amp;quot;API Hosts and Auth | Bluesky Protocol Services&amp;quot;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=405</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=405"/>
		<updated>2025-11-17T05:56:20Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├── experiments/&lt;br /&gt;
│     ├── coap_5001_6001/    → Riset 1 (ROI + Ascon via CoAP)&lt;br /&gt;
│     ├── coap_5002_6002/    → Riset 2 (App-layer vs OSCORE)&lt;br /&gt;
│     ├── coap_5003_6003/    → Riset 3 (NanoCipher – AEAD Design)&lt;br /&gt;
│     └── coap_5004_6004/    → Riset 4 (NanoCipher + OSCORE)&lt;br /&gt;
│&lt;br /&gt;
├── libcoap/                 → CoAP library + OSCORE integration&lt;br /&gt;
│&lt;br /&gt;
└── shared/&lt;br /&gt;
      ├── images/&lt;br /&gt;
      │      ├── 640x360/&lt;br /&gt;
      │      ├── 1280x720/&lt;br /&gt;
      │      └── 1920x1080/&lt;br /&gt;
      │&lt;br /&gt;
      └── algorithms/&lt;br /&gt;
             ├── ascon/&lt;br /&gt;
             ├── present/&lt;br /&gt;
             ├── chacha20/&lt;br /&gt;
             └── nanocipher/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Untuk kode dapat dilihat pada https://gitlab.com/aditbgoode/disertasi/&lt;br /&gt;
&lt;br /&gt;
===Skema===&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/                         # dataset (akan digunakan untuk R1–R4 pakai)&lt;br /&gt;
│  │  ├─ 640x360/  1280x720/  1920x1080/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs &amp;amp; wrappers&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (ascon_aead_cli + Makefile)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk Riset-3/Riset-4&lt;br /&gt;
├─ libcoap/                           # libcoap (diambil dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/                 # R1 artefak&lt;br /&gt;
   │  ├─ client/&lt;br /&gt;
   │  │  ├─ bin/                      # ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │  │  ├─ scripts/                  # detect_poi.py, encrypt_roi_ascon.py, run_r1.sh&lt;br /&gt;
   │  │  └─ processed_r1/&lt;br /&gt;
   │  │     ├─ 640x360/ 1280x720/ 1920x1080/&lt;br /&gt;
   │  └─ libcoap_client/&lt;br /&gt;
   │     └─ coap-client&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs di server juga&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (build server)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk R3/R4&lt;br /&gt;
├─ libcoap/                           # libcoap (dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/&lt;br /&gt;
   │  └─ server/&lt;br /&gt;
   │     ├─ bin/                      # coap-echo-server, ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │     ├─ inbox/&lt;br /&gt;
   │     ├─ tmp/&lt;br /&gt;
   │     ├─ decrypted/&lt;br /&gt;
   │     └─ logs/&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=404</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=404"/>
		<updated>2025-11-17T05:56:00Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/home/noble/&lt;br /&gt;
├── experiments/&lt;br /&gt;
│     ├── coap_5001_6001/    → Riset 1 (ROI + Ascon via CoAP)&lt;br /&gt;
│     ├── coap_5002_6002/    → Riset 2 (App-layer vs OSCORE)&lt;br /&gt;
│     ├── coap_5003_6003/    → Riset 3 (NanoCipher – AEAD Design)&lt;br /&gt;
│     └── coap_5004_6004/    → Riset 4 (NanoCipher + OSCORE)&lt;br /&gt;
│&lt;br /&gt;
├── libcoap/                 → CoAP library + OSCORE integration&lt;br /&gt;
│&lt;br /&gt;
└── shared/&lt;br /&gt;
      ├── images/&lt;br /&gt;
      │      ├── 640x360/&lt;br /&gt;
      │      ├── 1280x720/&lt;br /&gt;
      │      └── 1920x1080/&lt;br /&gt;
      │&lt;br /&gt;
      └── algorithms/&lt;br /&gt;
             ├── ascon/&lt;br /&gt;
             ├── present/&lt;br /&gt;
             ├── chacha20/&lt;br /&gt;
             └── nanocipher/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Untuk kode dapat dilihat pada https://gitlab.com/aditbgoode/disertasi/&lt;br /&gt;
&lt;br /&gt;
===Skema===&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/                         # dataset (akan digunakan untuk R1–R4 pakai)&lt;br /&gt;
│  │  ├─ 640x360/  1280x720/  1920x1080/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs &amp;amp; wrappers&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (ascon_aead_cli + Makefile)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk Riset-3/Riset-4&lt;br /&gt;
├─ libcoap/                           # libcoap (diambil dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/                 # R1 artefak&lt;br /&gt;
   │  ├─ client/&lt;br /&gt;
   │  │  ├─ bin/                      # ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │  │  ├─ scripts/                  # detect_poi.py, encrypt_roi_ascon.py, run_r1.sh&lt;br /&gt;
   │  │  └─ processed_r1/&lt;br /&gt;
   │  │     ├─ 640x360/ 1280x720/ 1920x1080/&lt;br /&gt;
   │  └─ libcoap_client/&lt;br /&gt;
   │     └─ coap-client&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs di server juga&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (build server)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk R3/R4&lt;br /&gt;
├─ libcoap/                           # libcoap (dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/&lt;br /&gt;
   │  └─ server/&lt;br /&gt;
   │     ├─ bin/                      # coap-echo-server, ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │     ├─ inbox/&lt;br /&gt;
   │     ├─ tmp/&lt;br /&gt;
   │     ├─ decrypted/&lt;br /&gt;
   │     └─ logs/&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=403</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=403"/>
		<updated>2025-11-04T03:03:33Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Untuk kode dapat dilihat pada https://gitlab.com/aditbgoode/disertasi/&lt;br /&gt;
&lt;br /&gt;
===Skema===&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/                         # dataset (akan digunakan untuk R1–R4 pakai)&lt;br /&gt;
│  │  ├─ 640x360/  1280x720/  1920x1080/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs &amp;amp; wrappers&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (ascon_aead_cli + Makefile)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk Riset-3/Riset-4&lt;br /&gt;
├─ libcoap/                           # libcoap (diambil dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/                 # R1 artefak&lt;br /&gt;
   │  ├─ client/&lt;br /&gt;
   │  │  ├─ bin/                      # ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │  │  ├─ scripts/                  # detect_poi.py, encrypt_roi_ascon.py, run_r1.sh&lt;br /&gt;
   │  │  └─ processed_r1/&lt;br /&gt;
   │  │     ├─ 640x360/ 1280x720/ 1920x1080/&lt;br /&gt;
   │  └─ libcoap_client/&lt;br /&gt;
   │     └─ coap-client&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs di server juga&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (build server)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk R3/R4&lt;br /&gt;
├─ libcoap/                           # libcoap (dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/&lt;br /&gt;
   │  └─ server/&lt;br /&gt;
   │     ├─ bin/                      # coap-echo-server, ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │     ├─ inbox/&lt;br /&gt;
   │     ├─ tmp/&lt;br /&gt;
   │     ├─ decrypted/&lt;br /&gt;
   │     └─ logs/&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=402</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=402"/>
		<updated>2025-11-04T03:02:41Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Untuk kode dapat dilihat pada https://gitlab.com/aditbgoode/disertasi/&lt;br /&gt;
&lt;br /&gt;
===Skema===&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/                         # dataset (akan digunakan untuk R1–R4 pakai)&lt;br /&gt;
│  │  ├─ 640x360/  1280x720/  1920x1080/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs &amp;amp; wrappers&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (dari github resmi)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (ascon_aead_cli + Makefile)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk Riset-3/Riset-4&lt;br /&gt;
├─ libcoap/                           # libcoap (diambil dari github resmi)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/                 # R1 artefak&lt;br /&gt;
   │  ├─ client/&lt;br /&gt;
   │  │  ├─ bin/                      # ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │  │  ├─ scripts/                  # detect_poi.py, encrypt_roi_ascon.py, run_r1.sh&lt;br /&gt;
   │  │  └─ processed_r1/&lt;br /&gt;
   │  │     ├─ 640x360/ 1280x720/ 1920x1080/&lt;br /&gt;
   │  └─ libcoap_client/&lt;br /&gt;
   │     └─ coap-client&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  └─ algorithms/                     # reusable libs di server juga&lt;br /&gt;
│     ├─ ascon/                       # upstream ascon-c (steril)&lt;br /&gt;
│     ├─ ascon_r1_cli/                # wrapper CLI utk R1 (build server)&lt;br /&gt;
│     ├─ nanocipher/                  # upstream NanoCipher&lt;br /&gt;
│     └─ nanocipher_r3_cli/           # wrapper NanoCipher utk R3/R4&lt;br /&gt;
├─ libcoap/                           # libcoap (build sekali per host)&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   ├─ coap_5001_6001/&lt;br /&gt;
   │  └─ server/&lt;br /&gt;
   │     ├─ bin/                      # coap-echo-server, ascon_aead_cli (copy dari shared/*_cli/build)&lt;br /&gt;
   │     ├─ inbox/&lt;br /&gt;
   │     ├─ tmp/&lt;br /&gt;
   │     ├─ decrypted/&lt;br /&gt;
   │     └─ logs/&lt;br /&gt;
   ├─ coap_5002_6002/                 # R2 artefak&lt;br /&gt;
   ├─ coap_5003_6003/                 # R3 artefak&lt;br /&gt;
   └─ coap_5004_6004/                 # R4 artefak&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=401</id>
		<title>Riset-1</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=401"/>
		<updated>2025-11-03T07:35:09Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Skema di Client dan Server==&lt;br /&gt;
&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/&lt;br /&gt;
│  │  ├─ 640x360/&lt;br /&gt;
│  │  ├─ 1280x720/&lt;br /&gt;
│  │  └─ 1920x1080/&lt;br /&gt;
│  └─ algorithms/&lt;br /&gt;
│     ├─ ascon/                 # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
│     └─ ascon_r1_cli/          # ← wrapper CLI khusus R1 (ascon_aead_cli.c, Makefile, build/)&lt;br /&gt;
│&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di CLIENT&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      ├─ client/&lt;br /&gt;
      │  ├─ bin/                # ← ascon_aead_cli (hasil build), tool lain&lt;br /&gt;
      │  ├─ scripts/            # ← detect_poi.py, encrypt_roi_ascon.py, run_r1.sh, models/&lt;br /&gt;
      │  └─ processed_r1/&lt;br /&gt;
      │     ├─ 640x360/&lt;br /&gt;
      │     ├─ 1280x720/&lt;br /&gt;
      │     └─ 1920x1080/&lt;br /&gt;
      └─ libcoap_client/&lt;br /&gt;
         └─ coap-client         # ← copy dari /home/noble/libcoap/examples/coap-client&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Catatan:&lt;br /&gt;
* shared/algorithms/ascon = repo asli upstream (tetap bersih).&lt;br /&gt;
* shared/algorithms/ascon_r1_cli = tempat ascon_aead_cli.c + Makefile + build/ (hasil make).&lt;br /&gt;
* Setelah make, copy build/ascon_aead_cli → experiments/coap_5001_6001/client/bin/.&lt;br /&gt;
* experiments/coap_5001_6001/libcoap_client/coap-client adalah binary dari libcoap (hasil build di /home/noble/libcoap).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di SERVER&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      └─ server/&lt;br /&gt;
         ├─ bin/&lt;br /&gt;
         │  ├─ coap-echo-server # ← copy dari /home/noble/libcoap/examples/coap-server (atau versi kustom)&lt;br /&gt;
         │  └─ ascon_aead_cli   # ← hasil build CLI di server (mirror dari client)&lt;br /&gt;
         ├─ aead_upstream/&lt;br /&gt;
         │  └─ ascon/           # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
         ├─ aead_cli_r1/&lt;br /&gt;
         │  ├─ ascon_aead_cli.c # ← copy dari client agar build lokal&lt;br /&gt;
         │  ├─ Makefile         # ← sesuaikan ASCON_UPSTREAM ke path server&lt;br /&gt;
         │  └─ build/&lt;br /&gt;
         ├─ inbox/              # ← simpan payload .txn.tar yang diterima&lt;br /&gt;
         ├─ tmp/                # ← tempat ekstrak .txn.tar untuk kerja sementara&lt;br /&gt;
         ├─ decrypted/          # ← hasil rekonstruksi (imgX.decrypted.png)&lt;br /&gt;
         └─ logs/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catatan:&lt;br /&gt;
* Build ascon_aead_cli di server (gunakan upstream lokal aead_upstream/ascon), lalu copy ke server/bin/.&lt;br /&gt;
* Jalankan coap-echo-server di -A 192.168.122.246 -p 6001.&lt;br /&gt;
* inbox/ menyimpan arsip payload masuk (bahan evaluasi).&lt;br /&gt;
* tmp/ untuk ekstraksi .txn.tar; decrypted/ hasil dekripsi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Untuk instalasi libcoap dapat dilihat pada [[libcoap]]&lt;br /&gt;
&lt;br /&gt;
==Client==&lt;br /&gt;
Siapkan struktur dan install dependency&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /home/noble/shared/images/{640x360,1280x720,1920x1080}&lt;br /&gt;
 mkdir -p /home/noble/shared/algorithms/{ascon,ascon_r1_cli}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/client/{bin,scripts,processed_r1}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/client/processed_r1/{640x360,1280x720,1920x1080}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/libcoap_client&lt;br /&gt;
 mkdir -p /home/noble/libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install -y \&lt;br /&gt;
  python3 python3-venv python3-opencv \&lt;br /&gt;
  build-essential autoconf automake libtool pkg-config \&lt;br /&gt;
  libssl-dev libpng-dev git&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Clone ascon-c dari github&lt;br /&gt;
&lt;br /&gt;
 cd /home/noble/shared/algorithms&lt;br /&gt;
 git clone https://github.com/ascon/ascon-c.git ascon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Siapkan ascon_r1_cli (wrapper) + Makefile + build script&lt;br /&gt;
&lt;br /&gt;
File: /home/noble/shared/algorithms/ascon_r1_cli/ascon_aead_cli.c dapat dilihat di &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Server==&lt;br /&gt;
Siapkan struktur dan install dependency&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /home/noble/shared/algorithms/{ascon,ascon_r1_cli}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/server/{bin,inbox,logs,tmp,decrypted}&lt;br /&gt;
 mkdir -p /home/noble/libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install -y \&lt;br /&gt;
  python3 python3-venv python3-opencv \&lt;br /&gt;
  build-essential autoconf automake libtool pkg-config \&lt;br /&gt;
  libssl-dev libpng-dev git&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=400</id>
		<title>Riset-1</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=400"/>
		<updated>2025-11-03T06:09:51Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Skema di Client dan Server==&lt;br /&gt;
&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/&lt;br /&gt;
│  │  ├─ 640x360/&lt;br /&gt;
│  │  ├─ 1280x720/&lt;br /&gt;
│  │  └─ 1920x1080/&lt;br /&gt;
│  └─ algorithms/&lt;br /&gt;
│     ├─ ascon/                 # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
│     └─ ascon_r1_cli/          # ← wrapper CLI khusus R1 (ascon_aead_cli.c, Makefile, build/)&lt;br /&gt;
│&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di CLIENT&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      ├─ client/&lt;br /&gt;
      │  ├─ bin/                # ← ascon_aead_cli (hasil build), tool lain&lt;br /&gt;
      │  ├─ scripts/            # ← detect_poi.py, encrypt_roi_ascon.py, run_r1.sh, models/&lt;br /&gt;
      │  └─ processed_r1/&lt;br /&gt;
      │     ├─ 640x360/&lt;br /&gt;
      │     ├─ 1280x720/&lt;br /&gt;
      │     └─ 1920x1080/&lt;br /&gt;
      └─ libcoap_client/&lt;br /&gt;
         └─ coap-client         # ← copy dari /home/noble/libcoap/examples/coap-client&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Catatan:&lt;br /&gt;
* shared/algorithms/ascon = repo asli upstream (tetap bersih).&lt;br /&gt;
* shared/algorithms/ascon_r1_cli = tempat ascon_aead_cli.c + Makefile + build/ (hasil make).&lt;br /&gt;
* Setelah make, copy build/ascon_aead_cli → experiments/coap_5001_6001/client/bin/.&lt;br /&gt;
* experiments/coap_5001_6001/libcoap_client/coap-client adalah binary dari libcoap (hasil build di /home/noble/libcoap).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di SERVER&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      └─ server/&lt;br /&gt;
         ├─ bin/&lt;br /&gt;
         │  ├─ coap-echo-server # ← copy dari /home/noble/libcoap/examples/coap-server (atau versi kustom)&lt;br /&gt;
         │  └─ ascon_aead_cli   # ← hasil build CLI di server (mirror dari client)&lt;br /&gt;
         ├─ aead_upstream/&lt;br /&gt;
         │  └─ ascon/           # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
         ├─ aead_cli_r1/&lt;br /&gt;
         │  ├─ ascon_aead_cli.c # ← copy dari client agar build lokal&lt;br /&gt;
         │  ├─ Makefile         # ← sesuaikan ASCON_UPSTREAM ke path server&lt;br /&gt;
         │  └─ build/&lt;br /&gt;
         ├─ inbox/              # ← simpan payload .txn.tar yang diterima&lt;br /&gt;
         ├─ tmp/                # ← tempat ekstrak .txn.tar untuk kerja sementara&lt;br /&gt;
         ├─ decrypted/          # ← hasil rekonstruksi (imgX.decrypted.png)&lt;br /&gt;
         └─ logs/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Catatan:&lt;br /&gt;
* Build ascon_aead_cli di server (gunakan upstream lokal aead_upstream/ascon), lalu copy ke server/bin/.&lt;br /&gt;
* Jalankan coap-echo-server di -A 192.168.122.246 -p 6001.&lt;br /&gt;
* inbox/ menyimpan arsip payload masuk (bahan evaluasi).&lt;br /&gt;
* tmp/ untuk ekstraksi .txn.tar; decrypted/ hasil dekripsi.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Client==&lt;br /&gt;
Siapkan struktur dan install dependency&lt;br /&gt;
&lt;br /&gt;
 mkdir -p /home/noble/shared/images/{640x360,1280x720,1920x1080}&lt;br /&gt;
 mkdir -p /home/noble/shared/algorithms/{ascon,ascon_r1_cli}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/client/{bin,scripts,processed_r1}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/client/processed_r1/{640x360,1280x720,1920x1080}&lt;br /&gt;
 mkdir -p /home/noble/experiments/coap_5001_6001/libcoap_client&lt;br /&gt;
 mkdir -p /home/noble/libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install -y \&lt;br /&gt;
  python3 python3-venv python3-opencv \&lt;br /&gt;
  build-essential autoconf automake libtool pkg-config \&lt;br /&gt;
  libssl-dev libpng-dev git&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Clone ascon-c dari github&lt;br /&gt;
&lt;br /&gt;
 cd /home/noble/shared/algorithms&lt;br /&gt;
 git clone https://github.com/ascon/ascon-c.git ascon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Siapkan ascon_r1_cli (wrapper) + Makefile + build script&lt;br /&gt;
&lt;br /&gt;
File: /home/noble/shared/algorithms/ascon_r1_cli/ascon_aead_cli.c&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=399</id>
		<title>Riset-1</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=399"/>
		<updated>2025-10-31T23:53:13Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Skema di Client dan Server==&lt;br /&gt;
&lt;br /&gt;
====Client====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ shared/&lt;br /&gt;
│  ├─ images/&lt;br /&gt;
│  │  ├─ 640x360/&lt;br /&gt;
│  │  ├─ 1280x720/&lt;br /&gt;
│  │  └─ 1920x1080/&lt;br /&gt;
│  └─ algorithms/&lt;br /&gt;
│     ├─ ascon/                 # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
│     └─ ascon_r1_cli/          # ← wrapper CLI khusus R1 (ascon_aead_cli.c, Makefile, build/)&lt;br /&gt;
│&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di CLIENT&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      ├─ client/&lt;br /&gt;
      │  ├─ bin/                # ← ascon_aead_cli (hasil build), tool lain&lt;br /&gt;
      │  ├─ scripts/            # ← detect_poi.py, encrypt_roi_ascon.py, run_r1.sh, models/&lt;br /&gt;
      │  └─ processed_r1/&lt;br /&gt;
      │     ├─ 640x360/&lt;br /&gt;
      │     ├─ 1280x720/&lt;br /&gt;
      │     └─ 1920x1080/&lt;br /&gt;
      └─ libcoap_client/&lt;br /&gt;
         └─ coap-client         # ← copy dari /home/noble/libcoap/examples/coap-client&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Catatan:&lt;br /&gt;
* shared/algorithms/ascon = repo asli upstream (tetap bersih).&lt;br /&gt;
* shared/algorithms/ascon_r1_cli = tempat ascon_aead_cli.c + Makefile + build/ (hasil make).&lt;br /&gt;
* Setelah make, copy build/ascon_aead_cli → experiments/coap_5001_6001/client/bin/.&lt;br /&gt;
* experiments/coap_5001_6001/libcoap_client/coap-client adalah binary dari libcoap (hasil build di /home/noble/libcoap).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Server====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ libcoap/                     # ← clone &amp;amp; build libcoap di SERVER&lt;br /&gt;
│&lt;br /&gt;
└─ experiments/&lt;br /&gt;
   └─ coap_5001_6001/&lt;br /&gt;
      └─ server/&lt;br /&gt;
         ├─ bin/&lt;br /&gt;
         │  ├─ coap-echo-server # ← copy dari /home/noble/libcoap/examples/coap-server (atau versi kustom)&lt;br /&gt;
         │  └─ ascon_aead_cli   # ← hasil build CLI di server (mirror dari client)&lt;br /&gt;
         ├─ aead_upstream/&lt;br /&gt;
         │  └─ ascon/           # ← clone upstream ascon-c (TANPA modifikasi)&lt;br /&gt;
         ├─ aead_cli_r1/&lt;br /&gt;
         │  ├─ ascon_aead_cli.c # ← copy dari client agar build lokal&lt;br /&gt;
         │  ├─ Makefile         # ← sesuaikan ASCON_UPSTREAM ke path server&lt;br /&gt;
         │  └─ build/&lt;br /&gt;
         ├─ inbox/              # ← simpan payload .txn.tar yang diterima&lt;br /&gt;
         ├─ tmp/                # ← tempat ekstrak .txn.tar untuk kerja sementara&lt;br /&gt;
         ├─ decrypted/          # ← hasil rekonstruksi (imgX.decrypted.png)&lt;br /&gt;
         └─ logs/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=398</id>
		<title>Riset-1</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=398"/>
		<updated>2025-10-31T11:56:30Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/home/noble/&lt;br /&gt;
├─ experiments/&lt;br /&gt;
│  └─ coap_5001_6001/&lt;br /&gt;
│     ├─ client/&lt;br /&gt;
│     │  ├─ bin/                # helper CLI (ascon_aead_cli, packer)&lt;br /&gt;
│     │  ├─ scripts/            # python &amp;amp; bash pipeline&lt;br /&gt;
│     │  └─ processed_r1/       # hasil siap kirim (akan dihapus tiap run)&lt;br /&gt;
│     └─ server/&lt;br /&gt;
│        ├─ bin/                # coap-server custom (opsional)&lt;br /&gt;
│        └─ inbox/              # hasil echo dari server (sementara)&lt;br /&gt;
├─ libcoap/                      # libcoap (client/server)&lt;br /&gt;
└─ shared/&lt;br /&gt;
   ├─ images/                    # 640x360 / 1280x720 / 1920x1080 (asli)&lt;br /&gt;
   └─ algorithms/&lt;br /&gt;
      └─ ascon/                  # referensi C untuk Ascon (lib + CLI kecil)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=397</id>
		<title>Riset-1</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-1&amp;diff=397"/>
		<updated>2025-10-29T02:19:21Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;/home/noble/ ├─ experiments/ │  └─ coap_5001_6001/ │     ├─ client/ │     │  ├─ bin/                # helper CLI (ascon_aead_cli, packer) │     │...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/home/noble/&lt;br /&gt;
├─ experiments/&lt;br /&gt;
│  └─ coap_5001_6001/&lt;br /&gt;
│     ├─ client/&lt;br /&gt;
│     │  ├─ bin/                # helper CLI (ascon_aead_cli, packer)&lt;br /&gt;
│     │  ├─ scripts/            # python &amp;amp; bash pipeline&lt;br /&gt;
│     │  └─ processed_r1/       # hasil siap kirim (akan dihapus tiap run)&lt;br /&gt;
│     └─ server/&lt;br /&gt;
│        ├─ bin/                # coap-server custom (opsional)&lt;br /&gt;
│        └─ inbox/              # hasil echo dari server (sementara)&lt;br /&gt;
├─ libcoap/                      # libcoap (client/server)&lt;br /&gt;
└─ shared/&lt;br /&gt;
   ├─ images/                    # 640x360 / 1280x720 / 1920x1080 (asli)&lt;br /&gt;
   └─ algorithms/&lt;br /&gt;
      └─ ascon/                  # referensi C untuk Ascon (lib + CLI kecil)&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=396</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=396"/>
		<updated>2025-10-29T02:18:14Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=395</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=395"/>
		<updated>2025-10-29T02:17:32Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
#* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
#* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
#* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
&lt;br /&gt;
# Privasi visual&lt;br /&gt;
#* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
# Perbandingan overhead antar layer&lt;br /&gt;
#* Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
#* Payload size (besar header tambahan OSCORE).&lt;br /&gt;
#* CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
&lt;br /&gt;
# Reliabilitas komunikasi&lt;br /&gt;
#* Packet retransmission / packet loss.&lt;br /&gt;
#* Goodput (gambar/MBps efektif).&lt;br /&gt;
&lt;br /&gt;
# Security&lt;br /&gt;
#* Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
#* App-layer: selective encryption, lebih hemat.&lt;br /&gt;
#* Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
&lt;br /&gt;
# Platform diversity&lt;br /&gt;
#* Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
#* Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
# Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
#* Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
#* Throughput (MB/s).&lt;br /&gt;
#* Code size (flash, KB).&lt;br /&gt;
#* RAM usage.&lt;br /&gt;
#* Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
&lt;br /&gt;
# Keamanan algoritma&lt;br /&gt;
#* Correctness: Known Answer Test (KAT).&lt;br /&gt;
#* Nonce misuse resistance (uji basic).&lt;br /&gt;
#* Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
&lt;br /&gt;
# Perbandingan dengan cipher lain&lt;br /&gt;
#* Ascon.&lt;br /&gt;
#* PRESENT.&lt;br /&gt;
#* ChaCha20.&lt;br /&gt;
#* AES.&lt;br /&gt;
&lt;br /&gt;
# Integrasi&lt;br /&gt;
#* Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
#* Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Integrasi OSCORE&lt;br /&gt;
#* Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
#* Kinerja encode/decode OSCORE.&lt;br /&gt;
&lt;br /&gt;
# Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
#* Latency per message.&lt;br /&gt;
#* Payload overhead.&lt;br /&gt;
#* CPU usage.&lt;br /&gt;
#* Energy consumption.&lt;br /&gt;
&lt;br /&gt;
# Robustness&lt;br /&gt;
#* Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
#* Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
&lt;br /&gt;
# Resource impact (IoT)&lt;br /&gt;
#* Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
#* Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=394</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=394"/>
		<updated>2025-10-29T02:15:19Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
#* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
#* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
#* Payload size (bytes dikirim).&lt;br /&gt;
#* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
1. Perbandingan overhead antar layer&lt;br /&gt;
   * Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
   * Payload size (besar header tambahan OSCORE).&lt;br /&gt;
   * CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
2. Reliabilitas komunikasi&lt;br /&gt;
   * Packet retransmission / packet loss.&lt;br /&gt;
   * Goodput (gambar/MBps efektif).&lt;br /&gt;
3. Security&lt;br /&gt;
   * Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
   * App-layer: selective encryption, lebih hemat.&lt;br /&gt;
   * Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
4. Platform diversity&lt;br /&gt;
   * Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
   * Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
1. Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
   * Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
   * Throughput (MB/s).&lt;br /&gt;
   * Code size (flash, KB).&lt;br /&gt;
   * RAM usage.&lt;br /&gt;
   * Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
2. Keamanan algoritma&lt;br /&gt;
   * Correctness: Known Answer Test (KAT).&lt;br /&gt;
   * Nonce misuse resistance (uji basic).&lt;br /&gt;
   * Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
3. Perbandingan dengan cipher lain&lt;br /&gt;
   * Ascon.&lt;br /&gt;
   * PRESENT.&lt;br /&gt;
   * ChaCha20.&lt;br /&gt;
   * AES.&lt;br /&gt;
4. Integrasi&lt;br /&gt;
   * Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
   * Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Integrasi OSCORE&lt;br /&gt;
   * Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
   * Kinerja encode/decode OSCORE.&lt;br /&gt;
2. Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
   * Latency per message.&lt;br /&gt;
   * Payload overhead.&lt;br /&gt;
   * CPU usage.&lt;br /&gt;
   * Energy consumption.&lt;br /&gt;
3. Robustness&lt;br /&gt;
   * Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
   * Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
4. Resource impact (IoT)&lt;br /&gt;
   * Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
   * Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=393</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=393"/>
		<updated>2025-10-29T02:14:54Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
# Kinerja sistem&lt;br /&gt;
* CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
* Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
* Payload size (bytes dikirim).&lt;br /&gt;
* Retransmisi (via pcap).&lt;br /&gt;
# QoE (Quality of Experience)&lt;br /&gt;
* SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
* SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
# Cryptographic footprint&lt;br /&gt;
* Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
# Privasi visual&lt;br /&gt;
* Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
1. Perbandingan overhead antar layer&lt;br /&gt;
   * Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
   * Payload size (besar header tambahan OSCORE).&lt;br /&gt;
   * CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
2. Reliabilitas komunikasi&lt;br /&gt;
   * Packet retransmission / packet loss.&lt;br /&gt;
   * Goodput (gambar/MBps efektif).&lt;br /&gt;
3. Security&lt;br /&gt;
   * Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
   * App-layer: selective encryption, lebih hemat.&lt;br /&gt;
   * Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
4. Platform diversity&lt;br /&gt;
   * Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
   * Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
1. Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
   * Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
   * Throughput (MB/s).&lt;br /&gt;
   * Code size (flash, KB).&lt;br /&gt;
   * RAM usage.&lt;br /&gt;
   * Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
2. Keamanan algoritma&lt;br /&gt;
   * Correctness: Known Answer Test (KAT).&lt;br /&gt;
   * Nonce misuse resistance (uji basic).&lt;br /&gt;
   * Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
3. Perbandingan dengan cipher lain&lt;br /&gt;
   * Ascon.&lt;br /&gt;
   * PRESENT.&lt;br /&gt;
   * ChaCha20.&lt;br /&gt;
   * AES.&lt;br /&gt;
4. Integrasi&lt;br /&gt;
   * Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
   * Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Integrasi OSCORE&lt;br /&gt;
   * Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
   * Kinerja encode/decode OSCORE.&lt;br /&gt;
2. Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
   * Latency per message.&lt;br /&gt;
   * Payload overhead.&lt;br /&gt;
   * CPU usage.&lt;br /&gt;
   * Energy consumption.&lt;br /&gt;
3. Robustness&lt;br /&gt;
   * Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
   * Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
4. Resource impact (IoT)&lt;br /&gt;
   * Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
   * Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=392</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=392"/>
		<updated>2025-10-29T02:09:24Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]==&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Kinerja sistem&lt;br /&gt;
   * CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
   * Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
   * Payload size (bytes dikirim).&lt;br /&gt;
   * Retransmisi (via pcap).&lt;br /&gt;
2. QoE (Quality of Experience)&lt;br /&gt;
   * SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
   * SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
3. Cryptographic footprint&lt;br /&gt;
   * Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
4. Privasi visual&lt;br /&gt;
   * Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]==&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
1. Perbandingan overhead antar layer&lt;br /&gt;
   * Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
   * Payload size (besar header tambahan OSCORE).&lt;br /&gt;
   * CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
2. Reliabilitas komunikasi&lt;br /&gt;
   * Packet retransmission / packet loss.&lt;br /&gt;
   * Goodput (gambar/MBps efektif).&lt;br /&gt;
3. Security&lt;br /&gt;
   * Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
   * App-layer: selective encryption, lebih hemat.&lt;br /&gt;
   * Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
4. Platform diversity&lt;br /&gt;
   * Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
   * Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]==&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
1. Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
   * Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
   * Throughput (MB/s).&lt;br /&gt;
   * Code size (flash, KB).&lt;br /&gt;
   * RAM usage.&lt;br /&gt;
   * Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
2. Keamanan algoritma&lt;br /&gt;
   * Correctness: Known Answer Test (KAT).&lt;br /&gt;
   * Nonce misuse resistance (uji basic).&lt;br /&gt;
   * Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
3. Perbandingan dengan cipher lain&lt;br /&gt;
   * Ascon.&lt;br /&gt;
   * PRESENT.&lt;br /&gt;
   * ChaCha20.&lt;br /&gt;
   * AES.&lt;br /&gt;
4. Integrasi&lt;br /&gt;
   * Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
   * Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
==[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]==&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Integrasi OSCORE&lt;br /&gt;
   * Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
   * Kinerja encode/decode OSCORE.&lt;br /&gt;
2. Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
   * Latency per message.&lt;br /&gt;
   * Payload overhead.&lt;br /&gt;
   * CPU usage.&lt;br /&gt;
   * Energy consumption.&lt;br /&gt;
3. Robustness&lt;br /&gt;
   * Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
   * Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
4. Resource impact (IoT)&lt;br /&gt;
   * Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
   * Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=391</id>
		<title>Riset-disertasi</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Riset-disertasi&amp;diff=391"/>
		<updated>2025-10-29T02:08:14Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;Riset-1 (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001] =========================================== Tujuan: menunjukkan keunggulan selective encryption untu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Riset-1]] (ROI + Ascon via CoAP) → Paper Conference [port 5001 - 6001]&lt;br /&gt;
===========================================&lt;br /&gt;
Tujuan: menunjukkan keunggulan selective encryption untuk multimedia di IoT.&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Kinerja sistem&lt;br /&gt;
   * CPU usage / execution time enkripsi (per gambar, per resolusi).&lt;br /&gt;
   * Latency end-to-end (ClientA → ServerB).&lt;br /&gt;
   * Payload size (bytes dikirim).&lt;br /&gt;
   * Retransmisi (via pcap).&lt;br /&gt;
2. QoE (Quality of Experience)&lt;br /&gt;
   * SSIM/PSNR area non-ROI (harus ≈1 / ∞ → fidelity utuh).&lt;br /&gt;
   * SSIM area ROI (rendah → privasi terlindungi).&lt;br /&gt;
3. Cryptographic footprint&lt;br /&gt;
   * Distribusi bytes terenkripsi antar gambar/resolusi.&lt;br /&gt;
4. Privasi visual&lt;br /&gt;
   * Apakah ROI (misalnya wajah) tak terbaca setelah enkripsi.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[[Riset-2]] (App-layer vs Transport-layer vs Hybrid) → Paper Q1 [port 5002 - 6002]&lt;br /&gt;
==================================================&lt;br /&gt;
Tujuan: membandingkan keamanan di layer aplikasi (ROI+Ascon) vs layer transport (OSCORE) vs kombinasi keduanya (cross layer).&lt;br /&gt;
1. Perbandingan overhead antar layer&lt;br /&gt;
   * Latency (CoAP vs OSCORE vs ROI+Ascon+OSCORE).&lt;br /&gt;
   * Payload size (besar header tambahan OSCORE).&lt;br /&gt;
   * CPU usage: ROI+Ascon (app) vs OSCORE (transport).&lt;br /&gt;
2. Reliabilitas komunikasi&lt;br /&gt;
   * Packet retransmission / packet loss.&lt;br /&gt;
   * Goodput (gambar/MBps efektif).&lt;br /&gt;
3. Security&lt;br /&gt;
   * Transport: full payload protected, tapi tidak selective.&lt;br /&gt;
   * App-layer: selective encryption, lebih hemat.&lt;br /&gt;
   * Kombinasi: double protection, overhead lebih tinggi.&lt;br /&gt;
4. Platform diversity&lt;br /&gt;
   * Evaluasi di VM (GNS3) vs Raspberry Pi vs ESP32.&lt;br /&gt;
   * Apakah constraint hardware mempengaruhi performa signifikan.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[[Riset-3]] (NanoCipher – AEAD baru) → Paper Q1 [port 5003 - 6003]&lt;br /&gt;
=======================================&lt;br /&gt;
Tujuan: membuktikan NanoCipher sebagai AEAD ringan khusus multimedia.&lt;br /&gt;
Evaluasi inti (kriptografi + sistem):&lt;br /&gt;
1. Benchmark kriptografi (MCU/CPU level)&lt;br /&gt;
   * Cycles/byte (ukur dengan benchmark Ascon/PRESENT/ChaCha20).&lt;br /&gt;
   * Throughput (MB/s).&lt;br /&gt;
   * Code size (flash, KB).&lt;br /&gt;
   * RAM usage.&lt;br /&gt;
   * Energy/byte (estimasi via current measurement di Raspberry Pi/ESP32).&lt;br /&gt;
2. Keamanan algoritma&lt;br /&gt;
   * Correctness: Known Answer Test (KAT).&lt;br /&gt;
   * Nonce misuse resistance (uji basic).&lt;br /&gt;
   * Konsistensi constant-time (cek dengan alat timing).&lt;br /&gt;
3. Perbandingan dengan cipher lain&lt;br /&gt;
   * Ascon.&lt;br /&gt;
   * PRESENT.&lt;br /&gt;
   * ChaCha20.&lt;br /&gt;
   * AES.&lt;br /&gt;
4. Integrasi&lt;br /&gt;
   * Kirim gambar (via libcoap) dengan NanoCipher.&lt;br /&gt;
   * Latency, payload, CPU, QoE → dibandingkan Ascon/AES/ChaCha20/PRESENT.&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
[[Riset-4]] (NanoCipher + OSCORE) → Paper Q1 [port 5004 - 6004]&lt;br /&gt;
====================================&lt;br /&gt;
Tujuan: menguji apakah NanoCipher bisa jadi alternatif AEAD di OSCORE (transport security).&lt;br /&gt;
Evaluasi:&lt;br /&gt;
1. Integrasi OSCORE&lt;br /&gt;
   * Modifikasi libcoap → NanoCipher jadi AEAD opsional di COSE.&lt;br /&gt;
   * Kinerja encode/decode OSCORE.&lt;br /&gt;
2. Perbandingan OSCORE-AES vs OSCORE-Ascon vs OSCORE-NanoCipher&lt;br /&gt;
   * Latency per message.&lt;br /&gt;
   * Payload overhead.&lt;br /&gt;
   * CPU usage.&lt;br /&gt;
   * Energy consumption.&lt;br /&gt;
3. Robustness&lt;br /&gt;
   * Correctness (uji KAT + interop message decrypt).&lt;br /&gt;
   * Replay protection (uji ulang id_context, sequence number).&lt;br /&gt;
4. Resource impact (IoT)&lt;br /&gt;
   * Memory footprint tambahan bila OSCORE pakai NanoCipher.&lt;br /&gt;
   * Apakah Raspberry/ESP32 masih muat (RAM/flash).&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=PostgreSQL&amp;diff=390</id>
		<title>PostgreSQL</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=PostgreSQL&amp;diff=390"/>
		<updated>2025-06-08T03:41:23Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* Perintah */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''' Install PostgreSQL di Ubuntu 20.04.01'''&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt install postgresql postgresql-contrib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Cara akses PostgreSQL'''&lt;br /&gt;
&lt;br /&gt;
Jika kita mempunyai database dengan nama psql&lt;br /&gt;
&lt;br /&gt;
Cara 1&lt;br /&gt;
   sudo -i -u postgres&lt;br /&gt;
   psql &lt;br /&gt;
&lt;br /&gt;
Cara 2&lt;br /&gt;
   sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
Cara 3 (jika kita tidak akan menggunakan sudo - untuk user biasa)&lt;br /&gt;
Buat terlebih dahulu usernya&lt;br /&gt;
 sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
 postgres=# create database mydb;&lt;br /&gt;
 postgres=# create user myuser with encrypted password 'mypass';&lt;br /&gt;
 postgres=# grant all privileges on database mydb to myuser;&lt;br /&gt;
&lt;br /&gt;
 psql -U myuser mydb&lt;br /&gt;
&lt;br /&gt;
''' Perintah PostgreSQL '''&lt;br /&gt;
&lt;br /&gt;
'''Membuat user'''&lt;br /&gt;
   sudo -u postgres createuser --interactive&lt;br /&gt;
&lt;br /&gt;
'''Membuat database'''&lt;br /&gt;
   sudo -u postgres createdb &amp;lt;namadb&amp;gt;&lt;br /&gt;
atau&lt;br /&gt;
   sudo -i -u postgres&lt;br /&gt;
   psql &lt;br /&gt;
   create database &amp;lt;namadb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Cek database'''&lt;br /&gt;
   \list&lt;br /&gt;
&lt;br /&gt;
'''Pilih database'''&lt;br /&gt;
   \connect &amp;lt;namadb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Delete postgres user'''&lt;br /&gt;
 REASSIGN OWNED BY myuser TO postgres;&lt;br /&gt;
 DROP OWNED BY myuser;&lt;br /&gt;
 DROP USER myuser;&lt;br /&gt;
&lt;br /&gt;
===Untuk di server===&lt;br /&gt;
Selain setting security groups di server, setting juga di etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
 host     all     all     127.0.0.1/32     md5&lt;br /&gt;
 host     all     all     10.0.1.0/24     md5&lt;br /&gt;
&lt;br /&gt;
Dan di etc/postgresql/&amp;lt;version&amp;gt;/main/postgresql.conf&lt;br /&gt;
Edit postgresql.conf and change listen_address:&lt;br /&gt;
&lt;br /&gt;
 listen_addresses='*'&lt;br /&gt;
&lt;br /&gt;
===Perintah===&lt;br /&gt;
\c: Untuk memilih database. Contoh: \c mydb (memilih database bernama &amp;quot;mydb&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
\l atau \list: Untuk melihat daftar database.&lt;br /&gt;
&lt;br /&gt;
\d: Untuk melihat deskripsi relasi (tabel, urutan, tampilan, dll.).&lt;br /&gt;
&lt;br /&gt;
\dn: Untuk melihat daftar skema.&lt;br /&gt;
&lt;br /&gt;
\h: Untuk menampilkan bantuan tentang perintah psql.&lt;br /&gt;
&lt;br /&gt;
\q: Untuk keluar dari psql.&lt;br /&gt;
&lt;br /&gt;
\e: Untuk membuka editor teks untuk perintah terakhir yang dieksekusi.&lt;br /&gt;
&lt;br /&gt;
\a: Untuk beralih antara format output (selaras atau tidak selaras).&lt;br /&gt;
&lt;br /&gt;
\g: Untuk menjalankan perintah terakhir.&lt;br /&gt;
&lt;br /&gt;
\i: Untuk menjalankan skrip SQL dari file.&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* https://serverfault.com/questions/336596/opening-port-5432-on-ubuntu&lt;br /&gt;
* https://medium.com/coding-blocks/creating-user-database-and-adding-access-on-postgresql-8bfcd2f4a91e&lt;br /&gt;
* https://phoenixnap.com/kb/delete-postgres-user&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=PostgreSQL&amp;diff=389</id>
		<title>PostgreSQL</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=PostgreSQL&amp;diff=389"/>
		<updated>2025-06-08T03:20:39Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''' Install PostgreSQL di Ubuntu 20.04.01'''&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt install postgresql postgresql-contrib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' Cara akses PostgreSQL'''&lt;br /&gt;
&lt;br /&gt;
Jika kita mempunyai database dengan nama psql&lt;br /&gt;
&lt;br /&gt;
Cara 1&lt;br /&gt;
   sudo -i -u postgres&lt;br /&gt;
   psql &lt;br /&gt;
&lt;br /&gt;
Cara 2&lt;br /&gt;
   sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
Cara 3 (jika kita tidak akan menggunakan sudo - untuk user biasa)&lt;br /&gt;
Buat terlebih dahulu usernya&lt;br /&gt;
 sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
 postgres=# create database mydb;&lt;br /&gt;
 postgres=# create user myuser with encrypted password 'mypass';&lt;br /&gt;
 postgres=# grant all privileges on database mydb to myuser;&lt;br /&gt;
&lt;br /&gt;
 psql -U myuser mydb&lt;br /&gt;
&lt;br /&gt;
''' Perintah PostgreSQL '''&lt;br /&gt;
&lt;br /&gt;
'''Membuat user'''&lt;br /&gt;
   sudo -u postgres createuser --interactive&lt;br /&gt;
&lt;br /&gt;
'''Membuat database'''&lt;br /&gt;
   sudo -u postgres createdb &amp;lt;namadb&amp;gt;&lt;br /&gt;
atau&lt;br /&gt;
   sudo -i -u postgres&lt;br /&gt;
   psql &lt;br /&gt;
   create database &amp;lt;namadb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Cek database'''&lt;br /&gt;
   \list&lt;br /&gt;
&lt;br /&gt;
'''Pilih database'''&lt;br /&gt;
   \connect &amp;lt;namadb&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Delete postgres user'''&lt;br /&gt;
 REASSIGN OWNED BY myuser TO postgres;&lt;br /&gt;
 DROP OWNED BY myuser;&lt;br /&gt;
 DROP USER myuser;&lt;br /&gt;
&lt;br /&gt;
===Untuk di server===&lt;br /&gt;
Selain setting security groups di server, setting juga di etc/postgresql/&amp;lt;version&amp;gt;/main/pg_hba.conf&lt;br /&gt;
&lt;br /&gt;
 host     all     all     127.0.0.1/32     md5&lt;br /&gt;
 host     all     all     10.0.1.0/24     md5&lt;br /&gt;
&lt;br /&gt;
Dan di etc/postgresql/&amp;lt;version&amp;gt;/main/postgresql.conf&lt;br /&gt;
Edit postgresql.conf and change listen_address:&lt;br /&gt;
&lt;br /&gt;
 listen_addresses='*'&lt;br /&gt;
&lt;br /&gt;
===Perintah===&lt;br /&gt;
\c: Untuk memilih database. Contoh: \c mydb (memilih database bernama &amp;quot;mydb&amp;quot;).&lt;br /&gt;
\l atau \list: Untuk melihat daftar database.&lt;br /&gt;
\d: Untuk melihat deskripsi relasi (tabel, urutan, tampilan, dll.).&lt;br /&gt;
\dn: Untuk melihat daftar skema.&lt;br /&gt;
\h: Untuk menampilkan bantuan tentang perintah psql.&lt;br /&gt;
\q: Untuk keluar dari psql.&lt;br /&gt;
\e: Untuk membuka editor teks untuk perintah terakhir yang dieksekusi.&lt;br /&gt;
\a: Untuk beralih antara format output (selaras atau tidak selaras).&lt;br /&gt;
\g: Untuk menjalankan perintah terakhir.&lt;br /&gt;
\i: Untuk menjalankan skrip SQL dari file. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* https://serverfault.com/questions/336596/opening-port-5432-on-ubuntu&lt;br /&gt;
* https://medium.com/coding-blocks/creating-user-database-and-adding-access-on-postgresql-8bfcd2f4a91e&lt;br /&gt;
* https://phoenixnap.com/kb/delete-postgres-user&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Percobaan_libcoap_GNS3&amp;diff=388</id>
		<title>Percobaan libcoap GNS3</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Percobaan_libcoap_GNS3&amp;diff=388"/>
		<updated>2025-02-11T06:15:46Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Setting Default===&lt;br /&gt;
&lt;br /&gt;
Buat percobaan menggunakan GNS3 yang melibatkan 2 ubuntu, 1 hub, 1 NAT.&lt;br /&gt;
&lt;br /&gt;
====Langkah 1====&lt;br /&gt;
&lt;br /&gt;
Ubuntu akan dijadikan client dan server. Keduanya diinstall libcoap (tutorial dapat dilihat pada  [[libcoap]]).&lt;br /&gt;
&lt;br /&gt;
====Langkah 2====&lt;br /&gt;
Pada client, disimpan gambar yang akan dikirimkan. Berikan perintah seperti berikut&lt;br /&gt;
&lt;br /&gt;
'''Client'''&lt;br /&gt;
 ./coap-client -v 9 -m put coap://192.168.122.246/example_data -G 10 -w -b 1024 -d @example.jpg&lt;br /&gt;
&lt;br /&gt;
'''Server'''&lt;br /&gt;
 ./coap-server -v 9 -L 9&lt;br /&gt;
&lt;br /&gt;
Penjelasan:&lt;br /&gt;
* -m put: Metode PUT digunakan untuk mengirimkan data ke server. Dalam hal ini, kamu mengirimkan gambar example.jpg ke server.&lt;br /&gt;
* -d @example.jpg: Mengirimkan file gambar example.jpg ke server dalam blok.&lt;br /&gt;
* -L 9: Mengatur tingkat verbosity log ke level 9 (informasi yang lebih rinci).&lt;br /&gt;
* -G 10: Memberikan batasan untuk 10 blok.&lt;br /&gt;
* -w: Menunggu respons dari server setelah setiap permintaan.&lt;br /&gt;
* -b 1024: Mengatur ukuran blok menjadi 1024 byte.&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Percobaan_libcoap_GNS3&amp;diff=387</id>
		<title>Percobaan libcoap GNS3</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Percobaan_libcoap_GNS3&amp;diff=387"/>
		<updated>2025-02-11T06:15:08Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;===Setting Default===  Buat percobaan menggunakan GNS3 yang melibatkan 2 ubuntu, 1 hub, 1 NAT.  ====Langkah 1====  Ubuntu akan dijadikan client dan server. Keduanya diinstall...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Setting Default===&lt;br /&gt;
&lt;br /&gt;
Buat percobaan menggunakan GNS3 yang melibatkan 2 ubuntu, 1 hub, 1 NAT.&lt;br /&gt;
&lt;br /&gt;
====Langkah 1====&lt;br /&gt;
&lt;br /&gt;
Ubuntu akan dijadikan client dan server. Keduanya diinstall libcoap (tutorial dapat dilihat pada  [[libcoap]]).&lt;br /&gt;
&lt;br /&gt;
====Langkah 2====&lt;br /&gt;
Pada client, disimpan gambar yang akan dikirimkan. Berikan perintah seperti berikut&lt;br /&gt;
&lt;br /&gt;
'''Client'''&lt;br /&gt;
 ./coap-client -v 9 -m put coap://192.168.122.246/example_data -G 10 -w -b 1024 -d @example.jpg&lt;br /&gt;
&lt;br /&gt;
'''Server'''&lt;br /&gt;
 ./coap-server -v 9 -L 9&lt;br /&gt;
&lt;br /&gt;
Penjelasan:&lt;br /&gt;
-m put: Metode PUT digunakan untuk mengirimkan data ke server. Dalam hal ini, kamu mengirimkan gambar example.jpg ke server.&lt;br /&gt;
-d @example.jpg: Mengirimkan file gambar example.jpg ke server dalam blok.&lt;br /&gt;
-L 9: Mengatur tingkat verbosity log ke level 9 (informasi yang lebih rinci).&lt;br /&gt;
-G 10: Memberikan batasan untuk 10 blok.&lt;br /&gt;
-w: Menunggu respons dari server setelah setiap permintaan.&lt;br /&gt;
-b 1024: Mengatur ukuran blok menjadi 1024 byte.&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=386</id>
		<title>Libcoap</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=386"/>
		<updated>2025-02-11T06:06:19Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;libcoap adalah pustaka open-source yang dirancang untuk memfasilitasi pengembangan aplikasi berbasis protokol CoAP (Constrained Application Protocol). Pustaka ini menyediakan implementasi CoAP yang lengkap dan efisien untuk perangkat dengan sumber daya terbatas, menjadikannya ideal untuk aplikasi Internet of Things (IoT). Berikut adalah penjelasan detail mengenai libcoap:&lt;br /&gt;
&lt;br /&gt;
===Pengantar libcoap===&lt;br /&gt;
libcoap dikembangkan untuk mendukung kebutuhan komunikasi di jaringan yang memiliki keterbatasan bandwidth dan daya. Pustaka ini memberikan antarmuka yang sederhana dan fleksibel bagi pengembang untuk membangun aplikasi CoAP.&lt;br /&gt;
&lt;br /&gt;
===Fitur Utama===&lt;br /&gt;
#Implementasi Lengkap: libcoap menyediakan semua elemen dasar dari protokol CoAP, termasuk pengiriman dan penerimaan pesan, mekanisme pengiriman ulang, dan pengelolaan observasi.&lt;br /&gt;
#Dukungan Multicast: libcoap mendukung pengiriman pesan multicast, yang memungkinkan efisiensi komunikasi di jaringan dengan banyak perangkat.&lt;br /&gt;
#Dukungan untuk DTLS: Pustaka ini mendukung DTLS (Datagram Transport Layer Security) untuk menyediakan keamanan dalam komunikasi CoAP.&lt;br /&gt;
#Dukungan untuk Berbagai Platform: libcoap dapat diintegrasikan ke dalam berbagai platform dan sistem operasi, termasuk Linux, Windows, dan sistem berbasis embedded.&lt;br /&gt;
#Modular: Arsitektur libcoap yang modular memungkinkan pengguna untuk menyesuaikan dan memperluas fungsionalitas sesuai kebutuhan aplikasi.&lt;br /&gt;
&lt;br /&gt;
===Struktur dan Penggunaan===&lt;br /&gt;
libcoap biasanya digunakan dalam konteks aplikasi server dan klien:&lt;br /&gt;
#Klien CoAP: Mengirim permintaan ke server dan menerima respons.&lt;br /&gt;
#Server CoAP: Menerima permintaan dari klien dan memberikan respons yang sesuai.&lt;br /&gt;
&lt;br /&gt;
===API dan Fungsi===&lt;br /&gt;
libcoap menyediakan API (Application Programming Interface) yang memungkinkan pengembang untuk berinteraksi dengan protokol CoAP. Beberapa fungsi penting dalam API libcoap meliputi:&lt;br /&gt;
&lt;br /&gt;
#Pengaturan Klien dan Server: Fungsi untuk menginisialisasi dan mengkonfigurasi klien dan server CoAP.&lt;br /&gt;
#Pengiriman dan Penerimaan Pesan: Fungsi untuk mengirim permintaan dan menerima respons.&lt;br /&gt;
#Pengelolaan Observasi: Fungsi untuk mendaftar dan membatalkan pengamatan terhadap resource tertentu.&lt;br /&gt;
#Pengaturan Keamanan: Fungsi untuk mengkonfigurasi DTLS dan pengaturan keamanan lainnya.&lt;br /&gt;
&lt;br /&gt;
===Instalasi===&lt;br /&gt;
Untuk instalasi libcoap di server, dapat menuliskan&lt;br /&gt;
 git clone https://github.com/obgm/libcoap.git&lt;br /&gt;
&lt;br /&gt;
Pastikan sudah instalasi beberapa package berikut (sesuaikan jika berbeda)&lt;br /&gt;
&lt;br /&gt;
 sudo apt install autoconf automake libtool pkg-config&lt;br /&gt;
&lt;br /&gt;
Jangan lupa juga cek compiler&lt;br /&gt;
&lt;br /&gt;
 sudo apt install g++&lt;br /&gt;
 sudo apt install build-essential&lt;br /&gt;
 &lt;br /&gt;
Kemudian masuk ke folder libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo chmod 777 autogen.sh&lt;br /&gt;
 ./autogen.sh&lt;br /&gt;
 ./configure --disable-documentation --disable-dtls --with-openssl&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Minimal==&lt;br /&gt;
Akan kita coba komunikasi client-server yang sederhana menggunakan CoAP.&lt;br /&gt;
Ambil cource dari git&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/obgm/libcoap-minimal.git&lt;br /&gt;
 cd libcoap-minimal&lt;br /&gt;
 make&lt;br /&gt;
&lt;br /&gt;
Untuk running server, jalankan perintah&lt;br /&gt;
&lt;br /&gt;
 ./server&lt;br /&gt;
&lt;br /&gt;
Untuk client, coba kirimkan paket sederhana&lt;br /&gt;
&lt;br /&gt;
 coap-client -v GET coap://192.168.1.104/hello&lt;br /&gt;
&lt;br /&gt;
Server akan memberikan respon '''world'''&lt;br /&gt;
 ./server &lt;br /&gt;
 v:1 t:CON c:GET i:ad53 {} [ Uri-Path:hello, Request-Tag:0xbfb4674b ]&lt;br /&gt;
 v:1 t:ACK c:2.05 i:ad53 {} [ ] :: 'world'&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[esp]]&lt;br /&gt;
* [[esp-idf]]&lt;br /&gt;
* [[esp-eye]]&lt;br /&gt;
* [[percobaan libcoap GNS3]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Definisi tanya chatGPT&lt;br /&gt;
* https://components.espressif.com/components/espressif/coap/versions/4.3.5~1&lt;br /&gt;
* https://github.com/obgm/libcoap-minimal&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=385</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=385"/>
		<updated>2025-01-28T06:36:23Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* Koneksi menggunakan ssh */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.&lt;br /&gt;
&lt;br /&gt;
==Instalasi==&lt;br /&gt;
Pada ubuntu&lt;br /&gt;
&lt;br /&gt;
 add-apt-repository ppa:git-core/ppa &lt;br /&gt;
 apt update&lt;br /&gt;
 apt install git&lt;br /&gt;
&lt;br /&gt;
==Cara menggunakan git==&lt;br /&gt;
Untuk pertama kali, perlu kita setting beberapa hal:&lt;br /&gt;
&lt;br /&gt;
*Login git via terminal&lt;br /&gt;
&lt;br /&gt;
 git config --global user.name &amp;quot;username&amp;quot;&lt;br /&gt;
 git config --global user.email user@mail.com&lt;br /&gt;
 git config --list&lt;br /&gt;
&lt;br /&gt;
*Login dan buat repo di github.com atau gitlab.com&lt;br /&gt;
&lt;br /&gt;
*Cara setting agar dapat remote git dari file lokal&lt;br /&gt;
 git init&lt;br /&gt;
 git remote add origin git@github.com:UserNameGit/NamaRepository.git&lt;br /&gt;
&lt;br /&gt;
*Menambahkan file&lt;br /&gt;
 git add index.php&lt;br /&gt;
 git commit -m &amp;quot;first commit&amp;quot;&lt;br /&gt;
 git push origin master&lt;br /&gt;
&lt;br /&gt;
*Mengambil file&lt;br /&gt;
 git pull origin master&lt;br /&gt;
 &lt;br /&gt;
==Login ke github==&lt;br /&gt;
Cara login ke Github setelah tanggal 13 Agustus 2021 berbeda. Untuk melakukan autentikasi, tidak menggunakan password, namun menggunakan PAT (Personal Access Token). Cara mendapatkan PAT adalah:&lt;br /&gt;
Dari GitHub account, pilih '''Settings =&amp;gt; Developer Settings =&amp;gt; Personal Access Token =&amp;gt; Generate New Token (Give your password) =&amp;gt; isi form =&amp;gt; click Generate token =&amp;gt; Copy the generated Token'''&lt;br /&gt;
Jangan lupa untuk menyimpan token pada file agar mudah diingat.&lt;br /&gt;
&lt;br /&gt;
==Koneksi menggunakan ssh==&lt;br /&gt;
Buat kunci private dan public dahulu (bisa cek '''[[ssh]]''' untuk membuatnya).&lt;br /&gt;
Jangan lupa buat chmod 600.&lt;br /&gt;
&lt;br /&gt;
Copy hasil pub ke '''Settings =&amp;gt; SSH and GPG keys =&amp;gt; new SSH keys'''&lt;br /&gt;
  &lt;br /&gt;
Lalu &lt;br /&gt;
 ssh-add &amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Identity added: &amp;lt;kunci&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
Kemudian cek koneksi SSH&lt;br /&gt;
 ssh -T git@github.com&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Hi &amp;lt;username&amp;gt;! You've successfully authenticated, but GitHub does not provide shell access.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Agar dapat digunakan tanpa meng-add ssh manual, tambahkan file config di path ~/.ssh/config dan isi dengan&lt;br /&gt;
 # Github.com server&lt;br /&gt;
 Host github.com&lt;br /&gt;
 IdentityFile ~/.ssh/&amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* https://git-scm.com/&lt;br /&gt;
* https://www.niagahoster.co.id/blog/git-tutorial-dasar/&lt;br /&gt;
* https://stackoverflow.com/questions/68775869/support-for-password-authentication-was-removed-please-use-a-personal-access-to&lt;br /&gt;
* https://www.petanikode.com/github-ssh/&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=384</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=384"/>
		<updated>2025-01-28T06:34:36Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.&lt;br /&gt;
&lt;br /&gt;
==Instalasi==&lt;br /&gt;
Pada ubuntu&lt;br /&gt;
&lt;br /&gt;
 add-apt-repository ppa:git-core/ppa &lt;br /&gt;
 apt update&lt;br /&gt;
 apt install git&lt;br /&gt;
&lt;br /&gt;
==Cara menggunakan git==&lt;br /&gt;
Untuk pertama kali, perlu kita setting beberapa hal:&lt;br /&gt;
&lt;br /&gt;
*Login git via terminal&lt;br /&gt;
&lt;br /&gt;
 git config --global user.name &amp;quot;username&amp;quot;&lt;br /&gt;
 git config --global user.email user@mail.com&lt;br /&gt;
 git config --list&lt;br /&gt;
&lt;br /&gt;
*Login dan buat repo di github.com atau gitlab.com&lt;br /&gt;
&lt;br /&gt;
*Cara setting agar dapat remote git dari file lokal&lt;br /&gt;
 git init&lt;br /&gt;
 git remote add origin git@github.com:UserNameGit/NamaRepository.git&lt;br /&gt;
&lt;br /&gt;
*Menambahkan file&lt;br /&gt;
 git add index.php&lt;br /&gt;
 git commit -m &amp;quot;first commit&amp;quot;&lt;br /&gt;
 git push origin master&lt;br /&gt;
&lt;br /&gt;
*Mengambil file&lt;br /&gt;
 git pull origin master&lt;br /&gt;
 &lt;br /&gt;
==Login ke github==&lt;br /&gt;
Cara login ke Github setelah tanggal 13 Agustus 2021 berbeda. Untuk melakukan autentikasi, tidak menggunakan password, namun menggunakan PAT (Personal Access Token). Cara mendapatkan PAT adalah:&lt;br /&gt;
Dari GitHub account, pilih '''Settings =&amp;gt; Developer Settings =&amp;gt; Personal Access Token =&amp;gt; Generate New Token (Give your password) =&amp;gt; isi form =&amp;gt; click Generate token =&amp;gt; Copy the generated Token'''&lt;br /&gt;
Jangan lupa untuk menyimpan token pada file agar mudah diingat.&lt;br /&gt;
&lt;br /&gt;
==Koneksi menggunakan ssh==&lt;br /&gt;
Buat kunci private dan public dahulu (bisa cek [[ssh]] untuk membuatnya).&lt;br /&gt;
Jangan lupa buat chmod 600.&lt;br /&gt;
&lt;br /&gt;
Copy hasil pub ke '''Settings =&amp;gt; SSH and GPG keys =&amp;gt; new SSH keys'''&lt;br /&gt;
  &lt;br /&gt;
Lalu &lt;br /&gt;
 ssh-add &amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Identity added: &amp;lt;kunci&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
Kemudian cek koneksi SSH&lt;br /&gt;
 ssh -T git@github.com&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Hi &amp;lt;username&amp;gt;! You've successfully authenticated, but GitHub does not provide shell access.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Agar dapat digunakan tanpa meng-add ssh manual, tambahkan file config di path ~/.ssh/config dan isi dengan&lt;br /&gt;
 # Github.com server&lt;br /&gt;
 Host github.com&lt;br /&gt;
 IdentityFile ~/.ssh/&amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* https://git-scm.com/&lt;br /&gt;
* https://www.niagahoster.co.id/blog/git-tutorial-dasar/&lt;br /&gt;
* https://stackoverflow.com/questions/68775869/support-for-password-authentication-was-removed-please-use-a-personal-access-to&lt;br /&gt;
* https://www.petanikode.com/github-ssh/&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=383</id>
		<title>Git</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Git&amp;diff=383"/>
		<updated>2025-01-28T06:33:08Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&lt;br /&gt;
&lt;br /&gt;
Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.&lt;br /&gt;
&lt;br /&gt;
==Instalasi==&lt;br /&gt;
Pada ubuntu&lt;br /&gt;
&lt;br /&gt;
 add-apt-repository ppa:git-core/ppa &lt;br /&gt;
 apt update&lt;br /&gt;
 apt install git&lt;br /&gt;
&lt;br /&gt;
==Cara menggunakan git==&lt;br /&gt;
Untuk pertama kali, perlu kita setting beberapa hal:&lt;br /&gt;
&lt;br /&gt;
*Login git via terminal&lt;br /&gt;
&lt;br /&gt;
 git config --global user.name &amp;quot;username&amp;quot;&lt;br /&gt;
 git config --global user.email user@mail.com&lt;br /&gt;
 git config --list&lt;br /&gt;
&lt;br /&gt;
*Login dan buat repo di github.com atau gitlab.com&lt;br /&gt;
&lt;br /&gt;
*Cara setting agar dapat remote git dari file lokal&lt;br /&gt;
 git init&lt;br /&gt;
 git remote add origin git@github.com:UserNameGit/NamaRepository.git&lt;br /&gt;
&lt;br /&gt;
*Menambahkan file&lt;br /&gt;
 git add index.php&lt;br /&gt;
 git commit -m &amp;quot;first commit&amp;quot;&lt;br /&gt;
 git push origin master&lt;br /&gt;
&lt;br /&gt;
*Mengambil file&lt;br /&gt;
 git pull origin master&lt;br /&gt;
 &lt;br /&gt;
==Login ke github==&lt;br /&gt;
Cara login ke Github setelah tanggal 13 Agustus 2021 berbeda. Untuk melakukan autentikasi, tidak menggunakan password, namun menggunakan PAT (Personal Access Token). Cara mendapatkan PAT adalah:&lt;br /&gt;
Dari GitHub account, pilih '''Settings =&amp;gt; Developer Settings =&amp;gt; Personal Access Token =&amp;gt; Generate New Token (Give your password) =&amp;gt; isi form =&amp;gt; click Generate token =&amp;gt; Copy the generated Token'''&lt;br /&gt;
Jangan lupa untuk menyimpan token pada file agar mudah diingat.&lt;br /&gt;
&lt;br /&gt;
==Koneksi menggunakan ssh==&lt;br /&gt;
Buat kunci private dan public dahulu (bisa cek [[ssh]] untuk membuatnya).&lt;br /&gt;
Jangan lupa buat chmod 600.&lt;br /&gt;
&lt;br /&gt;
Copy hasil pub ke '''Settings =&amp;gt; SSH and GPG keys =&amp;gt; new SSH keys'''&lt;br /&gt;
  &lt;br /&gt;
Lalu &lt;br /&gt;
 ssh-add &amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Identity added: &amp;lt;kunci&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
Kemudian cek koneksi SSH&lt;br /&gt;
 ssh -T git@github.com&lt;br /&gt;
&lt;br /&gt;
Hasilnya '''Hi &amp;lt;username&amp;gt;! You've successfully authenticated, but GitHub does not provide shell access.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Agar dapat digunakan tanpa meng-add ssh manual, tambahkan file config di path ~/.ssh/config dan isi dengan&lt;br /&gt;
 # Github.com server&lt;br /&gt;
 Host github.com&lt;br /&gt;
 IdentityFile ~/.ssh/&amp;lt;kunci&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* https://git-scm.com/&lt;br /&gt;
* https://www.niagahoster.co.id/blog/git-tutorial-dasar/&lt;br /&gt;
* https://stackoverflow.com/questions/68775869/support-for-password-authentication-was-removed-please-use-a-personal-access-to&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Qpdf&amp;diff=382</id>
		<title>Qpdf</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Qpdf&amp;diff=382"/>
		<updated>2024-12-18T04:07:06Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===What is QPDF?===&lt;br /&gt;
&lt;br /&gt;
QPDF is a command-line program that does structural, content-preserving transformations on PDF files. It could have been called something like pdf-to-pdf. It also provides many useful capabilities to developers of PDF-producing software or for people who just want to look at the innards of a PDF file to learn more about how they work.&lt;br /&gt;
&lt;br /&gt;
QPDF is capable of creating linearized (also known as web-optimized) files and encrypted files. It is also capable of converting PDF files with object streams (also known as compressed objects) to files with no compressed objects or to generate object streams from files that don't have them (or even those that already do). QPDF also supports a special mode designed to allow you to edit the content of PDF files in a text editor. For more details, please see the documentation links below.&lt;br /&gt;
&lt;br /&gt;
QPDF includes support for merging and splitting PDFs through the ability to copy objects from one PDF file into another and to manipulate the list of pages in a PDF file. The QPDF library also makes it possible for you to create PDF files from scratch. In this mode, you are responsible for supplying all the contents of the file, while the QPDF library takes care off all the syntactical representation of the objects, creation of cross references tables and, if you use them, object streams, encryption, linearization, and other syntactic details.&lt;br /&gt;
&lt;br /&gt;
QPDF is not a PDF content creation library, a PDF viewer, or a program capable of converting PDF into other formats. In particular, QPDF knows nothing about the semantics of PDF content streams. If you are looking for something that can do that, you should look elsewhere. However, once you have a valid PDF file, QPDF can be used to transform that file in ways perhaps your original PDF creation can't handle. For example, programs generate simple PDF files but can't password-protect them, web-optimize them, or perform other transformations of that type.&lt;br /&gt;
&lt;br /&gt;
QPDF releases are hosted at its SourceForge project page and also as github releases. The source code and issues are on github. On SourceForge, you can find downloads. The public key used to sign qpdf source distributions has fingerprint C2C9 6B10 011F E009 E6D1 DF82 8A75 D109 9801 2C7E and can be found at https://q.ql.org/pubkey.asc or downloaded from a public key server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Instalasi===&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt-get install -y qpdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cara pakai===&lt;br /&gt;
&lt;br /&gt;
====Split Page====&lt;br /&gt;
Misal akan membagi menjadi 1 halaman PDF&lt;br /&gt;
&lt;br /&gt;
   qpdf --split-pages=1 &amp;lt;file-asli&amp;gt;.pdf abc.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya akan membuat file abc-1.pdf, abd-2.pdf, dan seterusnya (sebanyak jumlah halaman yang ada)&lt;br /&gt;
&lt;br /&gt;
====Menggabung Page====&lt;br /&gt;
&lt;br /&gt;
   qpdf --empty --pages abc-*.pdf -- &amp;lt;file-output&amp;gt;.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya file abc-1.pdf, abd-2.pdf, dan seterusnya akan digabung menjadi file-output.pdf &lt;br /&gt;
&lt;br /&gt;
====Mengambil per Halaman====&lt;br /&gt;
&lt;br /&gt;
 qpdf input.pdf --pages . 1-10 -- output.pdf&lt;br /&gt;
 qpdf --empty --pages input.pdf 1-5 -- outfile.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya akan terdapat file output yang terdiri dari halaman 1-10 atau halaman 1-5 dari file input&lt;br /&gt;
&lt;br /&gt;
===Referensi===&lt;br /&gt;
* http://qpdf.sourceforge.net/&lt;br /&gt;
* https://askubuntu.com/questions/221962/how-can-i-extract-a-page-range-a-part-of-a-pdf&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Qpdf&amp;diff=381</id>
		<title>Qpdf</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Qpdf&amp;diff=381"/>
		<updated>2024-12-18T04:06:27Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===What is QPDF?===&lt;br /&gt;
&lt;br /&gt;
QPDF is a command-line program that does structural, content-preserving transformations on PDF files. It could have been called something like pdf-to-pdf. It also provides many useful capabilities to developers of PDF-producing software or for people who just want to look at the innards of a PDF file to learn more about how they work.&lt;br /&gt;
&lt;br /&gt;
QPDF is capable of creating linearized (also known as web-optimized) files and encrypted files. It is also capable of converting PDF files with object streams (also known as compressed objects) to files with no compressed objects or to generate object streams from files that don't have them (or even those that already do). QPDF also supports a special mode designed to allow you to edit the content of PDF files in a text editor. For more details, please see the documentation links below.&lt;br /&gt;
&lt;br /&gt;
QPDF includes support for merging and splitting PDFs through the ability to copy objects from one PDF file into another and to manipulate the list of pages in a PDF file. The QPDF library also makes it possible for you to create PDF files from scratch. In this mode, you are responsible for supplying all the contents of the file, while the QPDF library takes care off all the syntactical representation of the objects, creation of cross references tables and, if you use them, object streams, encryption, linearization, and other syntactic details.&lt;br /&gt;
&lt;br /&gt;
QPDF is not a PDF content creation library, a PDF viewer, or a program capable of converting PDF into other formats. In particular, QPDF knows nothing about the semantics of PDF content streams. If you are looking for something that can do that, you should look elsewhere. However, once you have a valid PDF file, QPDF can be used to transform that file in ways perhaps your original PDF creation can't handle. For example, programs generate simple PDF files but can't password-protect them, web-optimize them, or perform other transformations of that type.&lt;br /&gt;
&lt;br /&gt;
QPDF releases are hosted at its SourceForge project page and also as github releases. The source code and issues are on github. On SourceForge, you can find downloads. The public key used to sign qpdf source distributions has fingerprint C2C9 6B10 011F E009 E6D1 DF82 8A75 D109 9801 2C7E and can be found at https://q.ql.org/pubkey.asc or downloaded from a public key server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Instalasi===&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt-get install -y qpdf&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Cara pakai===&lt;br /&gt;
&lt;br /&gt;
====Split Page====&lt;br /&gt;
Misal akan membagi menjadi 1 halaman PDF&lt;br /&gt;
&lt;br /&gt;
   qpdf --split-pages=1 &amp;lt;file-asli&amp;gt;.pdf abc.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya akan membuat file abc-1.pdf, abd-2.pdf, dan seterusnya (sebanyak jumlah halaman yang ada)&lt;br /&gt;
&lt;br /&gt;
====Menggabung Page====&lt;br /&gt;
&lt;br /&gt;
   qpdf --empty --pages abc-*.pdf -- &amp;lt;file-output&amp;gt;.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya file abc-1.pdf, abd-2.pdf, dan seterusnya akan digabung menjadi file-output.pdf &lt;br /&gt;
&lt;br /&gt;
====Mengambil per Halaman====&lt;br /&gt;
&lt;br /&gt;
 qpdf input.pdf --pages . 1-10 -- output.pdf&lt;br /&gt;
 qpdf --empty --pages infile.pdf 1-5 -- outfile.pdf&lt;br /&gt;
&lt;br /&gt;
Hasilnya akan terdapat file output yang terdiri dari halaman 1-10 atau halaman 1-5&lt;br /&gt;
&lt;br /&gt;
===Referensi===&lt;br /&gt;
* http://qpdf.sourceforge.net/&lt;br /&gt;
* https://askubuntu.com/questions/221962/how-can-i-extract-a-page-range-a-part-of-a-pdf&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=380</id>
		<title>Esp-eye</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=380"/>
		<updated>2024-11-09T09:14:28Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESP-Eye adalah sebuah modul pengembangan berbasis ESP32 yang dirancang khusus untuk aplikasi pengolahan gambar dan pengenalan wajah. Modul ini memiliki beberapa fitur kunci:&lt;br /&gt;
&lt;br /&gt;
#Kamera Terintegrasi: ESP-Eye dilengkapi dengan kamera yang memungkinkan pengguna untuk menangkap gambar atau video.&lt;br /&gt;
#Konektivitas: Modul ini mendukung koneksi Wi-Fi dan Bluetooth, yang memudahkan untuk terhubung dengan perangkat lain dan mengirim data.&lt;br /&gt;
#Pemrosesan Gambar: Dengan menggunakan kemampuan pemrosesan dari chip ESP32, ESP-Eye dapat melakukan beberapa tugas pengolahan gambar, termasuk deteksi wajah dan pengenalan objek.&lt;br /&gt;
#Antarmuka yang Mudah: ESP-Eye dirancang untuk mudah digunakan, sehingga pengembang dapat dengan cepat membuat prototipe aplikasi berbasis kamera.&lt;br /&gt;
#Kompatibilitas: Modul ini kompatibel dengan berbagai pustaka dan platform pemrograman, termasuk Arduino dan MicroPython, yang membuatnya lebih fleksibel untuk digunakan.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tambah project===&lt;br /&gt;
Kita akan gunakan [[esp-eye]] sebagai client. Sehingga harus instalasi [[esp-idf]] agar dapat di-build dan di-flash ke client. Kita ambil contoh yang sudah ada dari link https://components.espressif.com/components/espressif/coap/versions/4.3.5~1/examples. Buat folder baru&lt;br /&gt;
&lt;br /&gt;
 mkdir projects&lt;br /&gt;
 cd projects&lt;br /&gt;
&lt;br /&gt;
Tambahkan komponen libcoap&lt;br /&gt;
&lt;br /&gt;
  idf.py add-dependency &amp;quot;espressif/coap^4.3.5~1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_client&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_server&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_server&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Untuk config project (setting WiFi, IP server, dll). Untuk URI nya bisa gunakan '''coap://{IP SERVER}/example_data'''&lt;br /&gt;
&lt;br /&gt;
 idf.py menuconfig&lt;br /&gt;
&lt;br /&gt;
Untuk build&lt;br /&gt;
&lt;br /&gt;
 idf.py build&lt;br /&gt;
&lt;br /&gt;
Untuk flash project&lt;br /&gt;
&lt;br /&gt;
 idf.py flash&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log/monitoring yang terjadi&lt;br /&gt;
&lt;br /&gt;
 idf.py monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Jika ada error port''', tambahkan perintah&lt;br /&gt;
&lt;br /&gt;
 idf.py -p PORT flash monitor&lt;br /&gt;
 idf.py -p /dev/ttyUSB0 flash&lt;br /&gt;
 idf.py -p COM3 flash&lt;br /&gt;
&lt;br /&gt;
Cara mendapatkan port&lt;br /&gt;
&lt;br /&gt;
*Linux: Ketik perintah ini sebelum dan sesudah ESP32 dipasang &lt;br /&gt;
 ls /dev/tty*&lt;br /&gt;
*macOS: &lt;br /&gt;
 ls /dev/tty.* &lt;br /&gt;
 ls /dev/cu.*.&lt;br /&gt;
*Windows: Buka Device Manager, cek &amp;quot;Ports (COM &amp;amp; LPT)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Percobaan===&lt;br /&gt;
Setelah install libcoap, ambil code dari example coap-server.c. Dengan code tersebut, sesuaikan struktur dari COAP-CLIENT2-ROBUST (https://github.com/dsp-mc-itb/COAP_CLIENT2_ROBUST).&lt;br /&gt;
&lt;br /&gt;
Pada file CMakeList (yang ada di COAP-CLIENT2-ROBUST) -&amp;gt; edit (local_client -&amp;gt; local_server; Sensor_local_client -&amp;gt; Sensor_local_server)&lt;br /&gt;
&lt;br /&gt;
Setelah itu ketik&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cmake&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cmake -S . -B build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake --build .&lt;br /&gt;
 ./local_server -v 8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[libcoap]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Definisi tanya chatGPT&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=379</id>
		<title>Esp-eye</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=379"/>
		<updated>2024-11-09T09:13:54Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* Link Terkait */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESP-Eye adalah sebuah modul pengembangan berbasis ESP32 yang dirancang khusus untuk aplikasi pengolahan gambar dan pengenalan wajah. Modul ini memiliki beberapa fitur kunci:&lt;br /&gt;
&lt;br /&gt;
#Kamera Terintegrasi: ESP-Eye dilengkapi dengan kamera yang memungkinkan pengguna untuk menangkap gambar atau video.&lt;br /&gt;
#Konektivitas: Modul ini mendukung koneksi Wi-Fi dan Bluetooth, yang memudahkan untuk terhubung dengan perangkat lain dan mengirim data.&lt;br /&gt;
#Pemrosesan Gambar: Dengan menggunakan kemampuan pemrosesan dari chip ESP32, ESP-Eye dapat melakukan beberapa tugas pengolahan gambar, termasuk deteksi wajah dan pengenalan objek.&lt;br /&gt;
#Antarmuka yang Mudah: ESP-Eye dirancang untuk mudah digunakan, sehingga pengembang dapat dengan cepat membuat prototipe aplikasi berbasis kamera.&lt;br /&gt;
#Kompatibilitas: Modul ini kompatibel dengan berbagai pustaka dan platform pemrograman, termasuk Arduino dan MicroPython, yang membuatnya lebih fleksibel untuk digunakan.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tambah project===&lt;br /&gt;
Kita akan gunakan [[esp-eye]] sebagai client. Sehingga harus instalasi [[esp-idf]] agar dapat di-build dan di-flash ke client. Kita ambil contoh yang sudah ada dari link https://components.espressif.com/components/espressif/coap/versions/4.3.5~1/examples. Buat folder baru&lt;br /&gt;
&lt;br /&gt;
 mkdir projects&lt;br /&gt;
 cd projects&lt;br /&gt;
&lt;br /&gt;
Tambahkan komponen libcoap&lt;br /&gt;
&lt;br /&gt;
  idf.py add-dependency &amp;quot;espressif/coap^4.3.5~1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_client&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_server&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_server&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Untuk config project (setting WiFi, IP server, dll). Untuk URI nya bisa gunakan '''coap://{IP SERVER}/example_data'''&lt;br /&gt;
&lt;br /&gt;
 idf.py menuconfig&lt;br /&gt;
&lt;br /&gt;
Untuk build&lt;br /&gt;
&lt;br /&gt;
 idf.py build&lt;br /&gt;
&lt;br /&gt;
Untuk flash project&lt;br /&gt;
&lt;br /&gt;
 idf.py flash&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log/monitoring yang terjadi&lt;br /&gt;
&lt;br /&gt;
 idf.py monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Jika ada error port''', tambahkan perintah&lt;br /&gt;
&lt;br /&gt;
 idf.py -p PORT flash monitor&lt;br /&gt;
 idf.py -p /dev/ttyUSB0 flash&lt;br /&gt;
 idf.py -p COM3 flash&lt;br /&gt;
&lt;br /&gt;
Cara mendapatkan port&lt;br /&gt;
&lt;br /&gt;
*Linux: Ketik perintah ini sebelum dan sesudah ESP32 dipasang &lt;br /&gt;
 ls /dev/tty*&lt;br /&gt;
*macOS: &lt;br /&gt;
 ls /dev/tty.* &lt;br /&gt;
 ls /dev/cu.*.&lt;br /&gt;
*Windows: Buka Device Manager, cek &amp;quot;Ports (COM &amp;amp; LPT)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Percobaan===&lt;br /&gt;
Setelah install libcoap, ambil code dari example coap-server.c. Dengan code tersebut, sesuaikan struktur dari COAP-CLIENT2-ROBUST (https://github.com/dsp-mc-itb/COAP_CLIENT2_ROBUST).&lt;br /&gt;
&lt;br /&gt;
Pada file CMakeList (yang ada di COAP-CLIENT2-ROBUST) -&amp;gt; edit (local_client -&amp;gt; local_server; Sensor_local_client -&amp;gt; Sensor_local_server)&lt;br /&gt;
&lt;br /&gt;
Setelah itu ketik&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cmake&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cmake -S . -B build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake --build .&lt;br /&gt;
 ./local_server -v 8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* Definisi tanya chatGPT&lt;br /&gt;
* [[libcoap]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=378</id>
		<title>Esp-eye</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=378"/>
		<updated>2024-11-09T09:13:26Z</updated>

		<summary type="html">&lt;p&gt;Aditya: /* Link Terkait */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESP-Eye adalah sebuah modul pengembangan berbasis ESP32 yang dirancang khusus untuk aplikasi pengolahan gambar dan pengenalan wajah. Modul ini memiliki beberapa fitur kunci:&lt;br /&gt;
&lt;br /&gt;
#Kamera Terintegrasi: ESP-Eye dilengkapi dengan kamera yang memungkinkan pengguna untuk menangkap gambar atau video.&lt;br /&gt;
#Konektivitas: Modul ini mendukung koneksi Wi-Fi dan Bluetooth, yang memudahkan untuk terhubung dengan perangkat lain dan mengirim data.&lt;br /&gt;
#Pemrosesan Gambar: Dengan menggunakan kemampuan pemrosesan dari chip ESP32, ESP-Eye dapat melakukan beberapa tugas pengolahan gambar, termasuk deteksi wajah dan pengenalan objek.&lt;br /&gt;
#Antarmuka yang Mudah: ESP-Eye dirancang untuk mudah digunakan, sehingga pengembang dapat dengan cepat membuat prototipe aplikasi berbasis kamera.&lt;br /&gt;
#Kompatibilitas: Modul ini kompatibel dengan berbagai pustaka dan platform pemrograman, termasuk Arduino dan MicroPython, yang membuatnya lebih fleksibel untuk digunakan.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tambah project===&lt;br /&gt;
Kita akan gunakan [[esp-eye]] sebagai client. Sehingga harus instalasi [[esp-idf]] agar dapat di-build dan di-flash ke client. Kita ambil contoh yang sudah ada dari link https://components.espressif.com/components/espressif/coap/versions/4.3.5~1/examples. Buat folder baru&lt;br /&gt;
&lt;br /&gt;
 mkdir projects&lt;br /&gt;
 cd projects&lt;br /&gt;
&lt;br /&gt;
Tambahkan komponen libcoap&lt;br /&gt;
&lt;br /&gt;
  idf.py add-dependency &amp;quot;espressif/coap^4.3.5~1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_client&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_server&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_server&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Untuk config project (setting WiFi, IP server, dll). Untuk URI nya bisa gunakan '''coap://{IP SERVER}/example_data'''&lt;br /&gt;
&lt;br /&gt;
 idf.py menuconfig&lt;br /&gt;
&lt;br /&gt;
Untuk build&lt;br /&gt;
&lt;br /&gt;
 idf.py build&lt;br /&gt;
&lt;br /&gt;
Untuk flash project&lt;br /&gt;
&lt;br /&gt;
 idf.py flash&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log/monitoring yang terjadi&lt;br /&gt;
&lt;br /&gt;
 idf.py monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Jika ada error port''', tambahkan perintah&lt;br /&gt;
&lt;br /&gt;
 idf.py -p PORT flash monitor&lt;br /&gt;
 idf.py -p /dev/ttyUSB0 flash&lt;br /&gt;
 idf.py -p COM3 flash&lt;br /&gt;
&lt;br /&gt;
Cara mendapatkan port&lt;br /&gt;
&lt;br /&gt;
*Linux: Ketik perintah ini sebelum dan sesudah ESP32 dipasang &lt;br /&gt;
 ls /dev/tty*&lt;br /&gt;
*macOS: &lt;br /&gt;
 ls /dev/tty.* &lt;br /&gt;
 ls /dev/cu.*.&lt;br /&gt;
*Windows: Buka Device Manager, cek &amp;quot;Ports (COM &amp;amp; LPT)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Percobaan===&lt;br /&gt;
Setelah install libcoap, ambil code dari example coap-server.c. Dengan code tersebut, sesuaikan struktur dari COAP-CLIENT2-ROBUST (https://github.com/dsp-mc-itb/COAP_CLIENT2_ROBUST).&lt;br /&gt;
&lt;br /&gt;
Pada file CMakeList (yang ada di COAP-CLIENT2-ROBUST) -&amp;gt; edit (local_client -&amp;gt; local_server; Sensor_local_client -&amp;gt; Sensor_local_server)&lt;br /&gt;
&lt;br /&gt;
Setelah itu ketik&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cmake&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cmake -S . -B build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake --build .&lt;br /&gt;
 ./local_server -v 8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait ==&lt;br /&gt;
* [[libcoap]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=377</id>
		<title>Esp-eye</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Esp-eye&amp;diff=377"/>
		<updated>2024-11-09T09:12:54Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ESP-Eye adalah sebuah modul pengembangan berbasis ESP32 yang dirancang khusus untuk aplikasi pengolahan gambar dan pengenalan wajah. Modul ini memiliki beberapa fitur kunci:&lt;br /&gt;
&lt;br /&gt;
#Kamera Terintegrasi: ESP-Eye dilengkapi dengan kamera yang memungkinkan pengguna untuk menangkap gambar atau video.&lt;br /&gt;
#Konektivitas: Modul ini mendukung koneksi Wi-Fi dan Bluetooth, yang memudahkan untuk terhubung dengan perangkat lain dan mengirim data.&lt;br /&gt;
#Pemrosesan Gambar: Dengan menggunakan kemampuan pemrosesan dari chip ESP32, ESP-Eye dapat melakukan beberapa tugas pengolahan gambar, termasuk deteksi wajah dan pengenalan objek.&lt;br /&gt;
#Antarmuka yang Mudah: ESP-Eye dirancang untuk mudah digunakan, sehingga pengembang dapat dengan cepat membuat prototipe aplikasi berbasis kamera.&lt;br /&gt;
#Kompatibilitas: Modul ini kompatibel dengan berbagai pustaka dan platform pemrograman, termasuk Arduino dan MicroPython, yang membuatnya lebih fleksibel untuk digunakan.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tambah project===&lt;br /&gt;
Kita akan gunakan [[esp-eye]] sebagai client. Sehingga harus instalasi [[esp-idf]] agar dapat di-build dan di-flash ke client. Kita ambil contoh yang sudah ada dari link https://components.espressif.com/components/espressif/coap/versions/4.3.5~1/examples. Buat folder baru&lt;br /&gt;
&lt;br /&gt;
 mkdir projects&lt;br /&gt;
 cd projects&lt;br /&gt;
&lt;br /&gt;
Tambahkan komponen libcoap&lt;br /&gt;
&lt;br /&gt;
  idf.py add-dependency &amp;quot;espressif/coap^4.3.5~1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_client&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_server&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_server&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Untuk config project (setting WiFi, IP server, dll). Untuk URI nya bisa gunakan '''coap://{IP SERVER}/example_data'''&lt;br /&gt;
&lt;br /&gt;
 idf.py menuconfig&lt;br /&gt;
&lt;br /&gt;
Untuk build&lt;br /&gt;
&lt;br /&gt;
 idf.py build&lt;br /&gt;
&lt;br /&gt;
Untuk flash project&lt;br /&gt;
&lt;br /&gt;
 idf.py flash&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log/monitoring yang terjadi&lt;br /&gt;
&lt;br /&gt;
 idf.py monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Jika ada error port''', tambahkan perintah&lt;br /&gt;
&lt;br /&gt;
 idf.py -p PORT flash monitor&lt;br /&gt;
 idf.py -p /dev/ttyUSB0 flash&lt;br /&gt;
 idf.py -p COM3 flash&lt;br /&gt;
&lt;br /&gt;
Cara mendapatkan port&lt;br /&gt;
&lt;br /&gt;
*Linux: Ketik perintah ini sebelum dan sesudah ESP32 dipasang &lt;br /&gt;
 ls /dev/tty*&lt;br /&gt;
*macOS: &lt;br /&gt;
 ls /dev/tty.* &lt;br /&gt;
 ls /dev/cu.*.&lt;br /&gt;
*Windows: Buka Device Manager, cek &amp;quot;Ports (COM &amp;amp; LPT)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Percobaan===&lt;br /&gt;
Setelah install libcoap, ambil code dari example coap-server.c. Dengan code tersebut, sesuaikan struktur dari COAP-CLIENT2-ROBUST (https://github.com/dsp-mc-itb/COAP_CLIENT2_ROBUST).&lt;br /&gt;
&lt;br /&gt;
Pada file CMakeList (yang ada di COAP-CLIENT2-ROBUST) -&amp;gt; edit (local_client -&amp;gt; local_server; Sensor_local_client -&amp;gt; Sensor_local_server)&lt;br /&gt;
&lt;br /&gt;
Setelah itu ketik&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cmake&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cmake -S . -B build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake --build .&lt;br /&gt;
 ./local_server -v 8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Link Terkait ===&lt;br /&gt;
* [[libcoap]]&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=376</id>
		<title>Libcoap</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=376"/>
		<updated>2024-11-09T09:12:26Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;libcoap adalah pustaka open-source yang dirancang untuk memfasilitasi pengembangan aplikasi berbasis protokol CoAP (Constrained Application Protocol). Pustaka ini menyediakan implementasi CoAP yang lengkap dan efisien untuk perangkat dengan sumber daya terbatas, menjadikannya ideal untuk aplikasi Internet of Things (IoT). Berikut adalah penjelasan detail mengenai libcoap:&lt;br /&gt;
&lt;br /&gt;
===Pengantar libcoap===&lt;br /&gt;
libcoap dikembangkan untuk mendukung kebutuhan komunikasi di jaringan yang memiliki keterbatasan bandwidth dan daya. Pustaka ini memberikan antarmuka yang sederhana dan fleksibel bagi pengembang untuk membangun aplikasi CoAP.&lt;br /&gt;
&lt;br /&gt;
===Fitur Utama===&lt;br /&gt;
#Implementasi Lengkap: libcoap menyediakan semua elemen dasar dari protokol CoAP, termasuk pengiriman dan penerimaan pesan, mekanisme pengiriman ulang, dan pengelolaan observasi.&lt;br /&gt;
#Dukungan Multicast: libcoap mendukung pengiriman pesan multicast, yang memungkinkan efisiensi komunikasi di jaringan dengan banyak perangkat.&lt;br /&gt;
#Dukungan untuk DTLS: Pustaka ini mendukung DTLS (Datagram Transport Layer Security) untuk menyediakan keamanan dalam komunikasi CoAP.&lt;br /&gt;
#Dukungan untuk Berbagai Platform: libcoap dapat diintegrasikan ke dalam berbagai platform dan sistem operasi, termasuk Linux, Windows, dan sistem berbasis embedded.&lt;br /&gt;
#Modular: Arsitektur libcoap yang modular memungkinkan pengguna untuk menyesuaikan dan memperluas fungsionalitas sesuai kebutuhan aplikasi.&lt;br /&gt;
&lt;br /&gt;
===Struktur dan Penggunaan===&lt;br /&gt;
libcoap biasanya digunakan dalam konteks aplikasi server dan klien:&lt;br /&gt;
#Klien CoAP: Mengirim permintaan ke server dan menerima respons.&lt;br /&gt;
#Server CoAP: Menerima permintaan dari klien dan memberikan respons yang sesuai.&lt;br /&gt;
&lt;br /&gt;
===API dan Fungsi===&lt;br /&gt;
libcoap menyediakan API (Application Programming Interface) yang memungkinkan pengembang untuk berinteraksi dengan protokol CoAP. Beberapa fungsi penting dalam API libcoap meliputi:&lt;br /&gt;
&lt;br /&gt;
#Pengaturan Klien dan Server: Fungsi untuk menginisialisasi dan mengkonfigurasi klien dan server CoAP.&lt;br /&gt;
#Pengiriman dan Penerimaan Pesan: Fungsi untuk mengirim permintaan dan menerima respons.&lt;br /&gt;
#Pengelolaan Observasi: Fungsi untuk mendaftar dan membatalkan pengamatan terhadap resource tertentu.&lt;br /&gt;
#Pengaturan Keamanan: Fungsi untuk mengkonfigurasi DTLS dan pengaturan keamanan lainnya.&lt;br /&gt;
&lt;br /&gt;
===Instalasi===&lt;br /&gt;
Untuk instalasi libcoap di server, dapat menuliskan&lt;br /&gt;
 git clone https://github.com/obgm/libcoap.git&lt;br /&gt;
&lt;br /&gt;
Pastikan sudah instalasi beberapa package berikut (sesuaikan jika berbeda)&lt;br /&gt;
&lt;br /&gt;
 sudo apt install autoconf automake libtool pkg-config&lt;br /&gt;
&lt;br /&gt;
Jangan lupa juga cek compiler&lt;br /&gt;
&lt;br /&gt;
 sudo apt install g++&lt;br /&gt;
 sudo apt install build-essential&lt;br /&gt;
 &lt;br /&gt;
Kemudian masuk ke folder libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo chmod 777 autogen.sh&lt;br /&gt;
 ./autogen.sh&lt;br /&gt;
 ./configure --disable-documentation --disable-dtls --with-openssl&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Testing Minimal==&lt;br /&gt;
Akan kita coba komunikasi client-server yang sederhana menggunakan CoAP.&lt;br /&gt;
Ambil cource dari git&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/obgm/libcoap-minimal.git&lt;br /&gt;
 cd libcoap-minimal&lt;br /&gt;
 make&lt;br /&gt;
&lt;br /&gt;
Untuk running server, jalankan perintah&lt;br /&gt;
&lt;br /&gt;
 ./server&lt;br /&gt;
&lt;br /&gt;
Untuk client, coba kirimkan paket sederhana&lt;br /&gt;
&lt;br /&gt;
 coap-client -v GET coap://192.168.1.104/hello&lt;br /&gt;
&lt;br /&gt;
Server akan memberikan respon '''world'''&lt;br /&gt;
 ./server &lt;br /&gt;
 v:1 t:CON c:GET i:ad53 {} [ Uri-Path:hello, Request-Tag:0xbfb4674b ]&lt;br /&gt;
 v:1 t:ACK c:2.05 i:ad53 {} [ ] :: 'world'&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[esp]]&lt;br /&gt;
* [[esp-idf]]&lt;br /&gt;
* [[esp-eye]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Definisi tanya chatGPT&lt;br /&gt;
* https://components.espressif.com/components/espressif/coap/versions/4.3.5~1&lt;br /&gt;
* https://github.com/obgm/libcoap-minimal&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=375</id>
		<title>Libcoap</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Libcoap&amp;diff=375"/>
		<updated>2024-11-09T09:01:54Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;libcoap adalah pustaka open-source yang dirancang untuk memfasilitasi pengembangan aplikasi berbasis protokol CoAP (Constrained Application Protocol). Pustaka ini menyediakan implementasi CoAP yang lengkap dan efisien untuk perangkat dengan sumber daya terbatas, menjadikannya ideal untuk aplikasi Internet of Things (IoT). Berikut adalah penjelasan detail mengenai libcoap:&lt;br /&gt;
&lt;br /&gt;
===Pengantar libcoap===&lt;br /&gt;
libcoap dikembangkan untuk mendukung kebutuhan komunikasi di jaringan yang memiliki keterbatasan bandwidth dan daya. Pustaka ini memberikan antarmuka yang sederhana dan fleksibel bagi pengembang untuk membangun aplikasi CoAP.&lt;br /&gt;
&lt;br /&gt;
===Fitur Utama===&lt;br /&gt;
#Implementasi Lengkap: libcoap menyediakan semua elemen dasar dari protokol CoAP, termasuk pengiriman dan penerimaan pesan, mekanisme pengiriman ulang, dan pengelolaan observasi.&lt;br /&gt;
#Dukungan Multicast: libcoap mendukung pengiriman pesan multicast, yang memungkinkan efisiensi komunikasi di jaringan dengan banyak perangkat.&lt;br /&gt;
#Dukungan untuk DTLS: Pustaka ini mendukung DTLS (Datagram Transport Layer Security) untuk menyediakan keamanan dalam komunikasi CoAP.&lt;br /&gt;
#Dukungan untuk Berbagai Platform: libcoap dapat diintegrasikan ke dalam berbagai platform dan sistem operasi, termasuk Linux, Windows, dan sistem berbasis embedded.&lt;br /&gt;
#Modular: Arsitektur libcoap yang modular memungkinkan pengguna untuk menyesuaikan dan memperluas fungsionalitas sesuai kebutuhan aplikasi.&lt;br /&gt;
&lt;br /&gt;
===Struktur dan Penggunaan===&lt;br /&gt;
libcoap biasanya digunakan dalam konteks aplikasi server dan klien:&lt;br /&gt;
#Klien CoAP: Mengirim permintaan ke server dan menerima respons.&lt;br /&gt;
#Server CoAP: Menerima permintaan dari klien dan memberikan respons yang sesuai.&lt;br /&gt;
&lt;br /&gt;
===API dan Fungsi===&lt;br /&gt;
libcoap menyediakan API (Application Programming Interface) yang memungkinkan pengembang untuk berinteraksi dengan protokol CoAP. Beberapa fungsi penting dalam API libcoap meliputi:&lt;br /&gt;
&lt;br /&gt;
#Pengaturan Klien dan Server: Fungsi untuk menginisialisasi dan mengkonfigurasi klien dan server CoAP.&lt;br /&gt;
#Pengiriman dan Penerimaan Pesan: Fungsi untuk mengirim permintaan dan menerima respons.&lt;br /&gt;
#Pengelolaan Observasi: Fungsi untuk mendaftar dan membatalkan pengamatan terhadap resource tertentu.&lt;br /&gt;
#Pengaturan Keamanan: Fungsi untuk mengkonfigurasi DTLS dan pengaturan keamanan lainnya.&lt;br /&gt;
&lt;br /&gt;
===Instalasi===&lt;br /&gt;
Untuk instalasi libcoap di server, dapat menuliskan&lt;br /&gt;
 git clone https://github.com/obgm/libcoap.git&lt;br /&gt;
&lt;br /&gt;
Pastikan sudah instalasi beberapa package berikut (sesuaikan jika berbeda)&lt;br /&gt;
&lt;br /&gt;
 sudo apt install autoconf automake libtool pkg-config&lt;br /&gt;
&lt;br /&gt;
Jangan lupa juga cek compiler&lt;br /&gt;
&lt;br /&gt;
 sudo apt install g++&lt;br /&gt;
 sudo apt install build-essential&lt;br /&gt;
 &lt;br /&gt;
Kemudian masuk ke folder libcoap&lt;br /&gt;
&lt;br /&gt;
 sudo chmod 777 autogen.sh&lt;br /&gt;
 ./autogen.sh&lt;br /&gt;
 ./configure --disable-documentation --with-openssl&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
===Tambah project===&lt;br /&gt;
Kita akan gunakan [[esp-eye]] sebagai client. Sehingga harus instalasi [[esp-idf]] agar dapat di-build dan di-flash ke client. Kita ambil contoh yang sudah ada dari link https://components.espressif.com/components/espressif/coap/versions/4.3.5~1/examples. Buat folder baru&lt;br /&gt;
&lt;br /&gt;
 mkdir projects&lt;br /&gt;
 cd projects&lt;br /&gt;
&lt;br /&gt;
Tambahkan komponen libcoap&lt;br /&gt;
&lt;br /&gt;
  idf.py add-dependency &amp;quot;espressif/coap^4.3.5~1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_client&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ambil contoh coap_server&lt;br /&gt;
&lt;br /&gt;
 idf.py create-project-from-example &amp;quot;espressif/coap^4.3.5~1:coap_server&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Untuk config project (setting WiFi, IP server, dll). Untuk URI nya bisa gunakan '''coap://{IP SERVER}/example_data'''&lt;br /&gt;
&lt;br /&gt;
 idf.py menuconfig&lt;br /&gt;
&lt;br /&gt;
Untuk build&lt;br /&gt;
&lt;br /&gt;
 idf.py build&lt;br /&gt;
&lt;br /&gt;
Untuk flash project&lt;br /&gt;
&lt;br /&gt;
 idf.py flash&lt;br /&gt;
&lt;br /&gt;
Untuk melihat log/monitoring yang terjadi&lt;br /&gt;
&lt;br /&gt;
 idf.py monitor&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Jika ada error port''', tambahkan perintah&lt;br /&gt;
&lt;br /&gt;
 idf.py -p PORT flash monitor&lt;br /&gt;
 idf.py -p /dev/ttyUSB0 flash&lt;br /&gt;
 idf.py -p COM3 flash&lt;br /&gt;
&lt;br /&gt;
Cara mendapatkan port&lt;br /&gt;
&lt;br /&gt;
*Linux: Ketik perintah ini sebelum dan sesudah ESP32 dipasang &lt;br /&gt;
 ls /dev/tty*&lt;br /&gt;
*macOS: &lt;br /&gt;
 ls /dev/tty.* &lt;br /&gt;
 ls /dev/cu.*.&lt;br /&gt;
*Windows: Buka Device Manager, cek &amp;quot;Ports (COM &amp;amp; LPT)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Percobaan===&lt;br /&gt;
Setelah install libcoap, ambil code dari example coap-server.c. Dengan code tersebut, sesuaikan struktur dari COAP-CLIENT2-ROBUST (https://github.com/dsp-mc-itb/COAP_CLIENT2_ROBUST).&lt;br /&gt;
&lt;br /&gt;
Pada file CMakeList (yang ada di COAP-CLIENT2-ROBUST) -&amp;gt; edit (local_client -&amp;gt; local_server; Sensor_local_client -&amp;gt; Sensor_local_server)&lt;br /&gt;
&lt;br /&gt;
Setelah itu ketik&lt;br /&gt;
&lt;br /&gt;
 sudo apt install cmake&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cmake -S . -B build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake --build .&lt;br /&gt;
 ./local_server -v 8&lt;br /&gt;
&lt;br /&gt;
==Testing Minimal==&lt;br /&gt;
Akan kita coba komunikasi client-server yang sederhana menggunakan CoAP.&lt;br /&gt;
Ambil cource dari git&lt;br /&gt;
&lt;br /&gt;
 git clone https://github.com/obgm/libcoap-minimal.git&lt;br /&gt;
 cd libcoap-minimal&lt;br /&gt;
 make&lt;br /&gt;
&lt;br /&gt;
Untuk running server, jalankan perintah&lt;br /&gt;
&lt;br /&gt;
 ./server&lt;br /&gt;
&lt;br /&gt;
Untuk client, coba kirimkan paket sederhana&lt;br /&gt;
&lt;br /&gt;
 coap-client -v GET coap://192.168.1.104/hello&lt;br /&gt;
&lt;br /&gt;
Server akan memberikan respon '''world'''&lt;br /&gt;
 ./server &lt;br /&gt;
 v:1 t:CON c:GET i:ad53 {} [ Uri-Path:hello, Request-Tag:0xbfb4674b ]&lt;br /&gt;
 v:1 t:ACK c:2.05 i:ad53 {} [ ] :: 'world'&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[esp]]&lt;br /&gt;
* [[esp-idf]]&lt;br /&gt;
* [[esp-eye]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Definisi tanya chatGPT&lt;br /&gt;
* https://components.espressif.com/components/espressif/coap/versions/4.3.5~1&lt;br /&gt;
* https://github.com/obgm/libcoap-minimal&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Examaining_and_Analysis_Windows_Memory&amp;diff=374</id>
		<title>Examaining and Analysis Windows Memory</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Examaining_and_Analysis_Windows_Memory&amp;diff=374"/>
		<updated>2024-10-16T04:54:48Z</updated>

		<summary type="html">&lt;p&gt;Aditya: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Volatility 3 adalah versi terbaru dari alat analisis forensik memori Volatility, yang dirancang untuk membantu penyelidik forensik dan profesional keamanan dalam menganalisis dump memori (image memory) dari sistem komputer. Berikut adalah penjelasan lebih lanjut tentang fitur, kegunaan, dan arsitektur Volatility 3:&lt;br /&gt;
&lt;br /&gt;
====Fitur Utama====&lt;br /&gt;
#Dukungan untuk Berbagai Platform: Volatility 3 mendukung analisis untuk berbagai sistem operasi, termasuk Windows, Linux, dan macOS, menjadikannya alat yang fleksibel untuk analisis forensik memori.&lt;br /&gt;
#Modular dan Ekstensible: Dibangun dengan arsitektur modular, yang memungkinkan penambahan plugin baru dan peningkatan fungsionalitas dengan mudah. Ini memudahkan pengembang untuk menyesuaikan dan mengembangkan fitur baru.&lt;br /&gt;
#Penggunaan API: Menyediakan API yang lebih baik untuk interaksi dengan data memori, memungkinkan pengembang untuk membuat skrip dan alat tambahan yang dapat berfungsi dengan data yang dianalisis.&lt;br /&gt;
#Dukungan untuk Format Dump yang Beragam: Mampu bekerja dengan berbagai format dump memori, termasuk file raw, crash dumps, dan format lainnya, yang membuatnya lebih fleksibel dalam penerapannya.&lt;br /&gt;
#Peningkatan Kinerja: Memiliki optimasi untuk meningkatkan kecepatan dan efisiensi analisis, memungkinkan pemrosesan data memori yang lebih cepat.&lt;br /&gt;
&lt;br /&gt;
====Kegunaan====&lt;br /&gt;
#Analisis Forensik: Digunakan oleh penyelidik untuk menganalisis memori yang dicuri atau dump memori untuk menemukan jejak aktivitas malware, melakukan analisis malware, dan mengumpulkan bukti dalam penyelidikan keamanan.&lt;br /&gt;
#Identifikasi Proses dan Koneksi Jaringan: Memungkinkan pengguna untuk mengidentifikasi proses yang sedang berjalan, koneksi jaringan, dan aktivitas yang mencurigakan dalam memori.&lt;br /&gt;
#Investigasi Insiden: Berguna dalam konteks respon insiden untuk mendapatkan wawasan tentang apa yang terjadi pada sistem saat insiden terjadi.&lt;br /&gt;
#Pemeriksaan Aktivitas Pengguna: Memungkinkan analisis tentang aktivitas pengguna dan aplikasi untuk memahami perilaku sistem.&lt;br /&gt;
&lt;br /&gt;
====Arsitektur====&lt;br /&gt;
#Plugin: Volatility 3 menggunakan sistem plugin yang memungkinkan pengguna untuk menjalankan berbagai jenis analisis, seperti analisis proses, koneksi jaringan, sistem file, dan lebih banyak lagi.&lt;br /&gt;
#Dukungan Data: Dengan pendekatan yang lebih berbasis objek, Volatility 3 memudahkan pengelolaan dan interaksi dengan data memori yang dianalisis.&lt;br /&gt;
#Kompatibilitas dengan Versi Sebelumnya: Meskipun merupakan versi yang lebih baru, Volatility 3 dirancang untuk berfungsi dengan baik dengan sebagian besar fitur dari versi sebelumnya, sambil menawarkan fungsionalitas yang lebih kuat dan lebih fleksibel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
# FTK Imager&lt;br /&gt;
# Volatility&lt;br /&gt;
&lt;br /&gt;
===Experiment===&lt;br /&gt;
=====Ambil memory menggunakan FTK Imager=====&lt;br /&gt;
# Klik '''capture memory'''&lt;br /&gt;
# Arahkan lokasi memory akan disimpan di mana (ekstensi bisa .raw atau .mem)*&lt;br /&gt;
&lt;br /&gt;
=====Analisis menggunakan Volatility=====&lt;br /&gt;
Pastikan memiliki python (disarankan versi 3).&lt;br /&gt;
&lt;br /&gt;
Clone dari github&lt;br /&gt;
 git clone https://volatility3.readthedocs.io/en/latest/&lt;br /&gt;
&lt;br /&gt;
Di dalam folder volatility3, install requirement&lt;br /&gt;
 pip3 install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
Cek plugin yang dapat digunakan&lt;br /&gt;
 python vol.py -h&lt;br /&gt;
&lt;br /&gt;
Cara menggunakan&lt;br /&gt;
 python vol.py -f {path lokasi memory} {plugin}&lt;br /&gt;
 python vol.py -f {contoh/memory.raw} windows.info&lt;br /&gt;
&lt;br /&gt;
*Catatan: &lt;br /&gt;
&lt;br /&gt;
=====Format RAW=====&lt;br /&gt;
#Definisi: Format RAW (atau &amp;quot;raw memory dump&amp;quot;) adalah representasi mentah dari memori fisik sistem. Ini mencakup semua konten yang ada dalam RAM tanpa pengolahan lebih lanjut.&lt;br /&gt;
#Karakteristik: &lt;br /&gt;
##Ukuran File: File RAW biasanya lebih besar karena menyimpan semua data di memori, termasuk ruang kosong.&lt;br /&gt;
##Kecepatan: Proses pengambilan memori dalam format RAW cenderung lebih cepat karena tidak memerlukan pemrosesan tambahan.&lt;br /&gt;
##Detail Lengkap: Menyediakan representasi yang lebih lengkap dari memori, termasuk semua data yang tersimpan, struktur data, dan informasi sistem.&lt;br /&gt;
##Kompatibilitas: Format RAW umum dan dapat digunakan oleh banyak alat forensik dan analisis memori lainnya.&lt;br /&gt;
#Keterbatasan:&lt;br /&gt;
##Tidak Terstruktur: Data dalam format RAW tidak memiliki metadata atau struktur, sehingga memerlukan pemrosesan tambahan untuk analisis.&lt;br /&gt;
##Kesulitan Analisis: Mungkin lebih sulit untuk menganalisis tanpa alat yang tepat, karena data tidak diorganisir dalam format yang mudah dibaca.&lt;br /&gt;
&lt;br /&gt;
=====Format MEM=====&lt;br /&gt;
#Definisi: Format MEM (Memory Image) adalah format khusus yang dirancang untuk menyimpan dump memori dengan lebih terstruktur, sering kali mencakup metadata dan informasi tambahan.&lt;br /&gt;
#Karakteristik:&lt;br /&gt;
##Struktur dan Metadata: Format MEM sering menyertakan informasi tambahan seperti waktu pengambilan, informasi sistem, dan struktur data yang membuatnya lebih mudah dianalisis.&lt;br /&gt;
##Ukuran File: File MEM mungkin lebih kecil dibandingkan file RAW karena dapat melakukan kompresi atau menyimpan hanya data yang relevan.&lt;br /&gt;
##Dukungan untuk Analisis: Banyak alat analisis memori dan forensik lebih mudah bekerja dengan format MEM karena strukturnya yang lebih terorganisir.&lt;br /&gt;
#Keterbatasan:&lt;br /&gt;
##Kompleksitas: Proses capture dan penyimpanan dalam format MEM mungkin lebih kompleks dan memakan waktu dibandingkan dengan RAW.&lt;br /&gt;
##Kompatibilitas: Mungkin tidak semua alat mendukung format MEM, tergantung pada implementasi spesifik.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[Digital Forensics]]&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Modul kuliah Digital Forensic STEI ITB&lt;br /&gt;
* Definisi tanya ChatGPT&lt;br /&gt;
* https://www.exterro.com/digital-forensics-software/ftk-imager&lt;br /&gt;
* https://volatility3.readthedocs.io/en/latest/&lt;br /&gt;
* https://github.com/volatilityfoundation/volatility3&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
	<entry>
		<id>https://kontenbelajar.com/wiki/index.php?title=Examaining_and_Analysis_Windows_Memory&amp;diff=373</id>
		<title>Examaining and Analysis Windows Memory</title>
		<link rel="alternate" type="text/html" href="https://kontenbelajar.com/wiki/index.php?title=Examaining_and_Analysis_Windows_Memory&amp;diff=373"/>
		<updated>2024-10-16T04:52:05Z</updated>

		<summary type="html">&lt;p&gt;Aditya: Created page with &amp;quot;Volatility 3 adalah versi terbaru dari alat analisis forensik memori Volatility, yang dirancang untuk membantu penyelidik forensik dan profesional keamanan dalam menganalisis...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Volatility 3 adalah versi terbaru dari alat analisis forensik memori Volatility, yang dirancang untuk membantu penyelidik forensik dan profesional keamanan dalam menganalisis dump memori (image memory) dari sistem komputer. Berikut adalah penjelasan lebih lanjut tentang fitur, kegunaan, dan arsitektur Volatility 3:&lt;br /&gt;
&lt;br /&gt;
====Fitur Utama====&lt;br /&gt;
#Dukungan untuk Berbagai Platform: Volatility 3 mendukung analisis untuk berbagai sistem operasi, termasuk Windows, Linux, dan macOS, menjadikannya alat yang fleksibel untuk analisis forensik memori.&lt;br /&gt;
#Modular dan Ekstensible: Dibangun dengan arsitektur modular, yang memungkinkan penambahan plugin baru dan peningkatan fungsionalitas dengan mudah. Ini memudahkan pengembang untuk menyesuaikan dan mengembangkan fitur baru.&lt;br /&gt;
#Penggunaan API: Menyediakan API yang lebih baik untuk interaksi dengan data memori, memungkinkan pengembang untuk membuat skrip dan alat tambahan yang dapat berfungsi dengan data yang dianalisis.&lt;br /&gt;
#Dukungan untuk Format Dump yang Beragam: Mampu bekerja dengan berbagai format dump memori, termasuk file raw, crash dumps, dan format lainnya, yang membuatnya lebih fleksibel dalam penerapannya.&lt;br /&gt;
#Peningkatan Kinerja: Memiliki optimasi untuk meningkatkan kecepatan dan efisiensi analisis, memungkinkan pemrosesan data memori yang lebih cepat.&lt;br /&gt;
&lt;br /&gt;
====Kegunaan====&lt;br /&gt;
#Analisis Forensik: Digunakan oleh penyelidik untuk menganalisis memori yang dicuri atau dump memori untuk menemukan jejak aktivitas malware, melakukan analisis malware, dan mengumpulkan bukti dalam penyelidikan keamanan.&lt;br /&gt;
#Identifikasi Proses dan Koneksi Jaringan: Memungkinkan pengguna untuk mengidentifikasi proses yang sedang berjalan, koneksi jaringan, dan aktivitas yang mencurigakan dalam memori.&lt;br /&gt;
#Investigasi Insiden: Berguna dalam konteks respon insiden untuk mendapatkan wawasan tentang apa yang terjadi pada sistem saat insiden terjadi.&lt;br /&gt;
#Pemeriksaan Aktivitas Pengguna: Memungkinkan analisis tentang aktivitas pengguna dan aplikasi untuk memahami perilaku sistem.&lt;br /&gt;
&lt;br /&gt;
====Arsitektur====&lt;br /&gt;
#Plugin: Volatility 3 menggunakan sistem plugin yang memungkinkan pengguna untuk menjalankan berbagai jenis analisis, seperti analisis proses, koneksi jaringan, sistem file, dan lebih banyak lagi.&lt;br /&gt;
#Dukungan Data: Dengan pendekatan yang lebih berbasis objek, Volatility 3 memudahkan pengelolaan dan interaksi dengan data memori yang dianalisis.&lt;br /&gt;
#Kompatibilitas dengan Versi Sebelumnya: Meskipun merupakan versi yang lebih baru, Volatility 3 dirancang untuk berfungsi dengan baik dengan sebagian besar fitur dari versi sebelumnya, sambil menawarkan fungsionalitas yang lebih kuat dan lebih fleksibel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
# FTK Imager&lt;br /&gt;
# Volatility&lt;br /&gt;
&lt;br /&gt;
===Experiment===&lt;br /&gt;
=====Ambil memory menggunakan FTK Imager=====&lt;br /&gt;
# Klik '''capture memory'''&lt;br /&gt;
# Arahkan lokasi memory akan disimpan di mana (ekstensi bisa .raw atau .mem)*&lt;br /&gt;
&lt;br /&gt;
=====Analisis menggunakan Volatility=====&lt;br /&gt;
Pastikan memiliki python (disarankan versi 3).&lt;br /&gt;
&lt;br /&gt;
Clone dari github&lt;br /&gt;
 git clone https://volatility3.readthedocs.io/en/latest/&lt;br /&gt;
&lt;br /&gt;
Di dalam folder volatility3, install requirement&lt;br /&gt;
 pip3 install -r requirements.txt&lt;br /&gt;
&lt;br /&gt;
Cek plugin yang dapat digunakan&lt;br /&gt;
 python vol.py -h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Catatan: &lt;br /&gt;
&lt;br /&gt;
=====Format RAW=====&lt;br /&gt;
#Definisi: Format RAW (atau &amp;quot;raw memory dump&amp;quot;) adalah representasi mentah dari memori fisik sistem. Ini mencakup semua konten yang ada dalam RAM tanpa pengolahan lebih lanjut.&lt;br /&gt;
#Karakteristik: &lt;br /&gt;
##Ukuran File: File RAW biasanya lebih besar karena menyimpan semua data di memori, termasuk ruang kosong.&lt;br /&gt;
##Kecepatan: Proses pengambilan memori dalam format RAW cenderung lebih cepat karena tidak memerlukan pemrosesan tambahan.&lt;br /&gt;
##Detail Lengkap: Menyediakan representasi yang lebih lengkap dari memori, termasuk semua data yang tersimpan, struktur data, dan informasi sistem.&lt;br /&gt;
##Kompatibilitas: Format RAW umum dan dapat digunakan oleh banyak alat forensik dan analisis memori lainnya.&lt;br /&gt;
#Keterbatasan:&lt;br /&gt;
##Tidak Terstruktur: Data dalam format RAW tidak memiliki metadata atau struktur, sehingga memerlukan pemrosesan tambahan untuk analisis.&lt;br /&gt;
##Kesulitan Analisis: Mungkin lebih sulit untuk menganalisis tanpa alat yang tepat, karena data tidak diorganisir dalam format yang mudah dibaca.&lt;br /&gt;
&lt;br /&gt;
=====Format MEM=====&lt;br /&gt;
#Definisi: Format MEM (Memory Image) adalah format khusus yang dirancang untuk menyimpan dump memori dengan lebih terstruktur, sering kali mencakup metadata dan informasi tambahan.&lt;br /&gt;
#Karakteristik:&lt;br /&gt;
##Struktur dan Metadata: Format MEM sering menyertakan informasi tambahan seperti waktu pengambilan, informasi sistem, dan struktur data yang membuatnya lebih mudah dianalisis.&lt;br /&gt;
##Ukuran File: File MEM mungkin lebih kecil dibandingkan file RAW karena dapat melakukan kompresi atau menyimpan hanya data yang relevan.&lt;br /&gt;
##Dukungan untuk Analisis: Banyak alat analisis memori dan forensik lebih mudah bekerja dengan format MEM karena strukturnya yang lebih terorganisir.&lt;br /&gt;
#Keterbatasan:&lt;br /&gt;
##Kompleksitas: Proses capture dan penyimpanan dalam format MEM mungkin lebih kompleks dan memakan waktu dibandingkan dengan RAW.&lt;br /&gt;
##Kompatibilitas: Mungkin tidak semua alat mendukung format MEM, tergantung pada implementasi spesifik.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Link Terkait==&lt;br /&gt;
* [[Digital Forensics]]&lt;br /&gt;
&lt;br /&gt;
==Referensi==&lt;br /&gt;
* Modul kuliah Digital Forensic STEI ITB&lt;br /&gt;
* Definisi tanya ChatGPT&lt;br /&gt;
* https://www.exterro.com/digital-forensics-software/ftk-imager&lt;br /&gt;
* https://volatility3.readthedocs.io/en/latest/&lt;br /&gt;
* https://github.com/volatilityfoundation/volatility3&lt;/div&gt;</summary>
		<author><name>Aditya</name></author>
		
	</entry>
</feed>