0% menganggap dokumen ini bermanfaat (0 suara)
206 tayangan499 halaman

Struktur dan Aturan Identifier Python

Dokumen ini menjelaskan struktur bahasa pemrograman Python, termasuk sintaks dasar, kata kunci, dan aturan pembuatan identifier. Terdapat penjelasan mendetail tentang perbedaan antara variabel, fungsi, kelas, modul, dan objek, serta konvensi penulisan yang sesuai dengan PEP 8. Kesimpulannya, identifier adalah nama unik yang digunakan untuk mengidentifikasi elemen program dan harus mengikuti aturan sintaksis tertentu.

Diunggah oleh

Ade Sukmana
Hak Cipta
© All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai DOCX, PDF, TXT atau baca online di Scribd
0% menganggap dokumen ini bermanfaat (0 suara)
206 tayangan499 halaman

Struktur dan Aturan Identifier Python

Dokumen ini menjelaskan struktur bahasa pemrograman Python, termasuk sintaks dasar, kata kunci, dan aturan pembuatan identifier. Terdapat penjelasan mendetail tentang perbedaan antara variabel, fungsi, kelas, modul, dan objek, serta konvensi penulisan yang sesuai dengan PEP 8. Kesimpulannya, identifier adalah nama unik yang digunakan untuk mengidentifikasi elemen program dan harus mengikuti aturan sintaksis tertentu.

Diunggah oleh

Ade Sukmana
Hak Cipta
© All Rights Reserved
Kami menangani hak cipta konten dengan serius. Jika Anda merasa konten ini milik Anda, ajukan klaim di sini.
Format Tersedia
Unduh sebagai DOCX, PDF, TXT atau baca online di Scribd

### Struktur Bahasa Pemrograman Python (Versi Revisi)

#### **1. Sintaks Dasar**

- **Kata Kunci (Keywords)**

### Penjelasan Lengkap Keyword Python (Satu per Satu):

1. **`False`**

Nilai boolean yang mewakili "salah" (kebalikan dari `True`).

Contoh: `is_active = False`

2. **`None`**

Menunjukkan ketiadaan nilai (null). Bukan `0`, `False`, atau string


kosong.

Contoh: `result = None`

3. **`True`**

Nilai boolean yang mewakili "benar".

Contoh: `is_valid = True`

4. **`and`**

Operator logika **DAN**. Mengembalikan `True` jika kedua operand


benar.

Contoh: `if age > 17 and has_id:`

5. **`as`**

Memberikan alias pada modul/objek saat impor atau dengan konteks.

Contoh: `import pandas as pd`

6. **`assert`**
Mengecek kondisi, memicu `AssertionError` jika salah (umum untuk
debugging).

Contoh: `assert x > 0, "Nilai harus positif"`

7. **`async`**

Mendeklarasikan fungsi asinkron (untuk pemrograman konkurensi).

Contoh: `async def fetch_data():`

8. **`await`**

Menjeda eksekusi sampai tugas asinkron selesai.

Contoh: `result = await api_call()`

9. **`break`**

Menghentikan perulangan (`for`/`while`) secara paksa.

Contoh:

```python

while True:

if kondisi: break

```

10. **`class`**

Mendefinisikan kelas (blueprint untuk objek OOP).

Contoh: `class User:`

11. **`continue`**

Melompati iterasi saat ini dalam perulangan, melanjutkan ke iterasi


berikutnya.

Contoh:

```python

for i in range(5):
if i == 2: continue

print(i) # Output: 0,1,3,4

```

12. **`def`**

Mendeklarasikan fungsi.

Contoh: `def hitung_total():`

13. **`del`**

Menghapus referensi objek/variabel.

Contoh: `del my_list[0]` (menghapus elemen pertama list)

14. **`elif`**

Singkatan dari "else if". Percabangan setelah `if`.

Contoh:

```python

if x > 10: ...

elif x > 5: ...

```

15. **`else`**

Blok kode yang dijalankan ketika kondisi `if`/`elif` tidak terpenuhi.

Contoh:

```python

if usia < 18:

print("Anak-anak")

else:

print("Dewasa")

```
16. **`except`**

Menangkap exception (error) dalam blok `try-except`.

Contoh:

```python

try:

risky_operation()

except ValueError:

handle_error()

```

17. **`finally`**

Blok kode yang **selalu** dijalankan setelah `try-except`, baik ada


error maupun tidak.

Contoh:

```python

try:

open_file()

finally:

close_file() # Selalu dijalankan

```

18. **`for`**

Membuat perulangan iteratif.

Contoh: `for item in list:`

19. **`from`**

Mengimpor bagian spesifik dari modul.

Contoh: `from math import sqrt`


20. **`global`**

Mendeklarasikan variabel dalam lingkup global di dalam fungsi.

Contoh:

```python

counter = 0

def increment():

global counter

counter += 1

```

21. **`if`**

Percabangan kondisi dasar.

Contoh: `if nilai >= 75: print("Lulus")`

22. **`import`**

Mengimpor modul eksternal.

Contoh: `import os`

23. **`in`**

Mengecek keanggotaan (apakah nilai ada dalam sequence).

Contoh: `if "a" in ["a", "b", "c"]:`

24. **`is`**

Mengecek identitas objek (apakah dua variabel merujuk ke objek yang


sama di memori).

Contoh: `if x is None:`

25. **`lambda`**
Membuat fungsi anonim (tanpa nama) sederhana.

Contoh: `f = lambda x: x*2`

26. **`nonlocal`**

Mengakses variabel di lingkup **luar fungsi** (bukan global).

Contoh:

```python

def outer():

x = 10

def inner():

nonlocal x # Mengakses x dari fungsi outer

x = 20

```

27. **`not`**

Operator logika **BUKAN** (membalik nilai boolean).

Contoh: `if not is_empty:`

28. **`or`**

Operator logika **ATAU**. Mengembalikan `True` jika salah satu


operand benar.

Contoh: `if saldo <= 0 or pin_salah:`

29. **`pass`**

Penghias sintaksis (tidak melakukan apa-apa), digunakan agar kode


valid secara sintaks.

Contoh:

```python

def placeholder():

pass # Fungsi kosong


```

30. **`raise`**

Secara sengaja memicu exception (error).

Contoh: `raise ValueError("Input tidak valid")`

31. **`return`**

Mengembalikan nilai dari fungsi dan mengakhiri eksekusinya.

Contoh: `return total_harga`

32. **`try`**

Blok untuk mengetes kode yang mungkin menghasilkan error.

Contoh:

```python

try:

kode_berisiko()

except:

penanganan_error()

```

33. **`while`**

Perulangan selama kondisi bernilai `True`.

Contoh:

```python

while counter < 10:

print(counter)

counter += 1

```
34. **`with`**

Manajemen konteks (e.g., otomatis menutup file setelah digunakan).

Contoh:

```python

with open("[Link]") as f:

data = [Link]()

# File otomatis ditutup di sini

```

35. **`yield`**

Mengembalikan nilai dari generator (fungsi yang bisa di-pause).

Contoh:

```python

def generator():

yield 1

yield 2

```

> **Catatan**:

> - Semua keyword bersifat **case-sensitive** dan **tidak bisa diubah


maknanya**.

> - Jumlah keyword berbeda tiap versi Python (Python 3.11 memiliki 35
keyword).

> - Cek keyword terbaru dengan `import keyword; print([Link])`.

- **Pengidentifikasi (Identifiers)**

### **Identifier dalam Python**

**Identifier** adalah nama yang diberikan kepada elemen-elemen dalam


kode Python untuk mengidentifikasi variabel, fungsi, kelas, modul, atau
objek lainnya. Identifier berfungsi sebagai **label/referensi** yang
memungkinkan Anda mengakses dan memanipulasi data atau fungsi
dalam program.

---

#### **Aturan Pembuatan Identifier:**

1. **Karakter yang Diizinkan**:

- Huruf (a-z, A-Z)

- Angka (0-9)

- Underscore (`_`)

- *Contoh valid*: `nama`, `umur_1`, `TotalHarga`

2. **Tidak Boleh Dimulai dengan Angka**:

- ❌ Salah: `1_nama`

- ✅ Benar: `nama1`

3. **Case-Sensitive**:

- `nama` ≠ `Nama` ≠ `NAMA` (dianggap sebagai identifier berbeda).

4. **Tidak Boleh Sama dengan Keyword Python**:

- ❌ Salah: `if = 10` (karena `if` adalah keyword).

5. **Tidak Boleh Mengandung Spasi atau Simbol Khusus**:

- ❌ Salah: `total harga`, `user@email`.

---

#### **Jenis Identifier:**

1. **Variabel**
```python

jumlah_barang = 10 # 'jumlah_barang' adalah identifier

```

2. **Fungsi**

```python

def hitung_total(): # 'hitung_total' adalah identifier

pass

```

3. **Kelas**

```python

class UserProfile: # 'UserProfile' adalah identifier

pass

```

4. **Modul**

```python

import math # 'math' adalah identifier modul

```

5. **Objek**

```python

user = UserProfile() # 'user' adalah identifier objek

```

---

#### **Konvensi Penulisan (PEP 8):**


| Tipe | Gaya Penulisan | Contoh |

|-----------------|----------------------|--------------------|

| Variabel/Fungsi | Snake case | `total_harga`, `hitung_rata_rata()` |

| Kelas | Pascal case | `DataMahasiswa`, `Karyawan` |

| Konstanta | UPPER_SNAKE_CASE | `MAX_SIZE`, `PI` |

| Modul/Paket | Lowercase | `utils`, `model` |

---

#### **Identifier Khusus:**

- **Identifier yang Diawali Underscore (`_`)**:

- `_variabel`: Menandakan **private** (hanya untuk penggunaan


internal).

- `__variabel`: Menandakan **name mangling** (untuk menghindari


konflik nama di subclass).

- `__init__`: **Dunder method** (metode khusus Python).

---

#### **Contoh Valid vs Invalid:**

| Valid | Alasan | Invalid | Alasan |

|---------------|----------------------------|---------------|--------------------------------|

| `nama` | Karakter huruf | `2faktor` | Dimulai angka


|

| `_alamat` | Underscore di awal | `class` | Keyword Python


|

| `hitung2` | Angka di akhir | `total-harga` | Menggunakan


simbol (`-`) |

| `MAX_VALUE` | Konvensi konstanta | `first name` | Mengandung


spasi |
---

#### **Penting:**

- Identifier harus **deskriptif** dan mencerminkan tujuan penggunaannya.

Contoh:

❌ Buruk: `a = 100`

✅ Baik: `jumlah_produk = 100`

- Hindari identifier terlalu pendek (kecuali untuk variabel sementara


seperti `i`, `x` dalam loop).

---

### **Kesimpulan:**

Identifier adalah **nama unik** yang Anda buat untuk mengidentifikasi


elemen program. Dengan mengikuti aturan sintaksis dan konvensi PEP 8,
Anda akan menulis kode yang lebih bersih, mudah dibaca, dan bebas
error.

### **Perbedaan Variabel, Fungsi, Kelas, Modul, dan Objek dalam


Identifier Python**

#### **1. Variabel**

- **Definisi**: Nama yang merujuk ke nilai/data dalam memori.

- **Fungsi**: Menyimpan data (angka, string, objek, dll).

- **Ciri**:

- Tidak ada deklarasi eksplisit (dibuat saat assignment).

- Tipe data dinamis (berubah sesuai nilai).

- **Contoh**:

```python

jumlah = 10 # Variabel integer


nama = "Budi" # Variabel string

harga_total = 25000.0 # Variabel float

```

#### **2. Fungsi**

- **Definisi**: Blok kode bernama yang menjalankan tugas spesifik.

- **Fungsi**: Mengemas logika reusable, menerima input, mengembalikan


output.

- **Ciri**:

- Didefinisikan dengan `def`.

- Dapat memiliki parameter dan nilai kembali.

- **Contoh**:

```python

def hitung_total(harga, jumlah):

return harga * jumlah

```

#### **3. Kelas (Class)**

- **Definisi**: Blueprint/cetakan untuk membuat objek.

- **Fungsi**: Mendefinisikan struktur data (atribut) dan perilaku (metode).

- **Ciri**:

- Didefinisikan dengan `class`.

- Berisi metode (fungsi dalam kelas) dan atribut.

- **Contoh**:

```python

class Produk:

def __init__(self, nama, harga):

[Link] = nama # Atribut objek

[Link] = harga # Atribut objek


def info(self): # Metode

return f"{[Link]}: Rp{[Link]}"

```

#### **4. Objek (Object)**

- **Definisi**: Instance nyata yang dibuat dari kelas.

- **Fungsi**: Merepresentasikan entitas spesifik dengan data unik.

- **Ciri**:

- Dibuat dengan memanggil kelas seperti fungsi: `Kelas()`.

- Menyimpan state melalui atribut.

- **Contoh**:

```python

buku = Produk("Python Guide", 150000) # Objek

print([Link]()) # Output: "Python Guide: Rp150000"

```

#### **5. Modul**

- **Definisi**: File `.py` yang berisi kode Python (fungsi, kelas, variabel).

- **Fungsi**: Mengorganisasi kode menjadi unit reusable.

- **Ciri**:

- Diimpor dengan `import nama_modul`.

- Mengenkapsulasi kode terkait.

- **Contoh**:

```python

# File: [Link]

TAX_RATE = 0.1 # Variabel dalam modul

def calculate_tax(price): # Fungsi dalam modul


return price * TAX_RATE

# Penggunaan di file lain:

# import ecommerce

# print(ecommerce.calculate_tax(100000))

```

---

### **Ringkasan Perbedaan**

| **Konsep** | **Sifat** | **Cara Pembuatan** | **Contoh


Penggunaan** | **Lingkup** |

|-------------|--------------------|--------------------------|----------------------------|------------
---------|

| **Variabel** | Penyimpan data | Assignment (`=`) | `x = 10`


| Lokal/global/modul |

| **Fungsi** | Blok kode executable | `def nama_fungsi():` | `hasil =


hitung_total()` | Modul/kelas |

| **Kelas** | Template objek | `class NamaKelas:` | `class User:`


| Modul |

| **Objek** | Instance kelas | `obj = NamaKelas()` | `user1 =


User("Alice")` | Runtime |

| **Modul** | File kode | File `.py` | `import math`


| Sistem file |

---

### **Diagram Hubungan**

```

MODUL ([Link])


├── VARIABEL (data statis)

├── FUNGSI (logika independen)

└── KELAS (blueprint)

└── OBJEK (instance)

├── Atribut (variabel objek)

└── Metode (fungsi objek)

```

---

### **Contoh Integrasi**

```python

# MODUL: [Link]

# VARIABEL modul

DISKON = 0.2

# FUNGSI modul

def apply_discount(price):

return price * (1 - DISKON)

# KELAS

class Product:

def __init__(self, name, price):

[Link] = name # Atribut OBJEK

[Link] = price # Atribut OBJEK


# Metode OBJEK (fungsi dalam kelas)

def final_price(self):

return apply_discount([Link])

# Pembuatan OBJEK

pencil = Product("Pencil", 10000)

print(pencil.final_price()) # Output: 8000.0

```

---

### **Kesimpulan**

- **Variabel**: Penyimpan data dasar.

- **Fungsi**: Unit logika independen.

- **Kelas**: Cetakan untuk membuat objek.

- **Objek**: Entitas nyata dengan data dan perilaku spesifik.

- **Modul**: Wadah pengorganisasi kode tertinggi (file).

Setiap identifier memainkan peran hierarkis:

1. Modul mengelompokkan fungsi/kelas

2. Kelas menghasilkan objek

3. Objek mengandung variabel dan fungsi (metode)

4. Variabel dan fungsi dapat hidup di semua level!

-----------------------------------------------------------------------

- **Komentar (Comments)**

### **Comments (Komentar) dalam Python**


**Komentar** adalah teks dalam kode Python yang **tidak dieksekusi**
oleh interpreter. Fungsinya untuk memberikan penjelasan, dokumentasi,
atau catatan untuk programmer lain (atau diri sendiri di masa depan)
tentang logika kode.

---

#### **Jenis Komentar:**

1. **Single-Line Comment (Komentar Satu Baris)**

Diawali dengan tanda pagar (`#`).

Contoh:

```python

# Menghitung total harga

total = harga * jumlah # Ini juga komentar

```

2. **Multi-Line Comment (Komentar Multi-Baris)**

- **Cara 1**: Gunakan `#` di setiap baris.

```python

# Fungsi ini digunakan untuk:

# 1. Validasi input user

# 2. Menyimpan data ke database

def proses_data():

pass

```

- **Cara 2**: Gunakan triple quotes (`"""..."""` atau `'''...'''`).

Biasanya digunakan untuk **docstrings** (dokumentasi


fungsi/kelas/modul).

```python
def hitung_rata_rata(angka):

"""

Menghitung rata-rata dari list angka.

Parameters:

angka (list): List berisi angka.

Returns:

float: Nilai rata-rata.

"""

return sum(angka) / len(angka)

```

---

#### **Fungsi & Manfaat Komentar:**

1. **Dokumentasi Kode**

Menjelaskan tujuan fungsi, kelas, atau modul.

2. **Penjelasan Logika Kompleks**

Misal: algoritma matematika atau alur kerja rumit.

3. **Debugging Sementara**

Menonaktifkan kode tanpa menghapusnya (disebut *commenting out*).

```python

# print("Nilai sementara:", hasil) # Dinonaktifkan untuk debugging

```

4. **Panduan untuk Pengembang**

Seperti TODO, FIXME, atau catatan penting.

```python

# TODO: Tambahkan validasi input


# FIXME: Perbaiki bug saat input kosong

```

---

#### **Best Practice (PEP 8):**

1. **Gunakan Bahasa Inggris**

Agar konsisten dan mudah dipahami secara global.

2. **Jangan Terlalu Berlebihan**

Komentar untuk hal yang tidak jelas dari kode, bukan yang sudah
obvious.

❌ Buruk: `x = 5 # assign 5 to x`

✅ Baik: `x = 5 # Batas maksimum percobaan login`

3. **Update Komentar**

Pastikan komentar relevan dengan kode terbaru (komentar usang lebih


buruk daripada tidak ada komentar).

4. **Gunakan Docstrings untuk Dokumentasi Publik**

Khususnya untuk fungsi/kelas/modul yang digunakan oleh orang lain.

```python

class User:

"""Kelas untuk mengelola data pengguna."""

def __init__(self, nama):

"""Inisialisasi objek User."""

[Link] = nama

```

---

#### **Contoh Penggunaan Efektif:**


```python

# Konversi suhu Celsius ke Fahrenheit

def celsius_ke_fahrenheit(celsius):

"""

Rumus: F = (C * 9/5) + 32

Parameters:

celsius (float): Suhu dalam Celsius.

Returns:

float: Suhu dalam Fahrenheit.

"""

return (celsius * 9/5) + 32

# Contoh penggunaan

# print(celsius_ke_fahrenheit(25)) # Output: 77.0

```

---

### **Perbedaan Komentar vs Docstring**

| **Komentar** (`#`) | **Docstring** (`"""..."""`) |

|-------------------------------------------|------------------------------------------|

| Untuk penjelasan internal/khusus. | Dokumentasi resmi (bisa


diakses via `help()`). |

| Tidak disimpan sebagai metadata. | Disimpan di atribut `__doc__`


objek. |

| Bisa di mana saja dalam kode. | Hanya di awal


modul/kelas/fungsi. |
```python

print(hitung_rata_rata.__doc__) # Menampilkan docstring

```

---

### **Kesimpulan:**

Komentar adalah alat vital untuk:

- Meningkatkan **keterbacaan** kode.

- Memudahkan **kolaborasi** tim.

- Membantu **pemeliharaan** kode jangka panjang.

Gunakan secara bijak: **"Kode yang baik menjelaskan dirinya sendiri,


tetapi komentar yang baik membuatnya sempurna."**

-----------------------------------------------------------------------

- **Pernyataan (Statements)**

### **Statements dalam Python**

**Statement** adalah unit dasar sintaksis dalam Python yang mewakili


**instruksi atau perintah** untuk dieksekusi oleh interpreter Python.
Setiap baris kode Python yang melakukan suatu tindakan adalah sebuah
statement.

---

#### **Ciri Khas Statement:**

1. **Menyebabkan Efek Samping**:


Mengubah state program (misal: assignment, modifikasi data).

2. **Tidak Menghasilkan Nilai Langsung**:

Berbeda dengan *expression* yang selalu menghasilkan nilai.

3. **Dapat Berisi Ekspresi**:

Statement sering mengandung ekspresi di dalamnya.

---

### **Jenis-Jenis Statement**

#### 1. **Assignment Statement**

(Pernyataan Penugasan)

Menyimpan nilai ke dalam variabel.

```python

x = 10

nama = "Alice"

hasil = x * 5 + 3 # Mengandung ekspresi matematika

```

#### 2. **Conditional Statement**

(Pernyataan Kondisional: `if`, `elif`, `else`)

Mengontrol alur program berdasarkan kondisi.

```python

if suhu > 30:

print("Panas")

elif suhu < 10:

print("Dingin")

else:

print("Sejuk")
```

#### 3. **Loop Statement**

(Pernyataan Perulangan: `for`, `while`)

Mengeksekusi blok kode berulang kali.

```python

# For loop

for i in range(5):

print(i)

# While loop

counter = 0

while counter < 3:

print(counter)

counter += 1

```

++++++++++++++++++++++++++++++++++

### Perbedaan Looping dan Iterasi dalam Pemrograman Python

#### **1. Looping (Perulangan)**

- **Definisi**:

Mekanisme untuk **mengeksekusi blok kode berulang kali** selama


kondisi tertentu terpenuhi.

- **Fungsi Utama**:

Mengotomatisasi pengulangan tugas tanpa menulis kode yang sama


berkali-kali.

- **Jenis di Python**:

- **`for` loop**: Untuk iterasi melalui urutan (list, tuple, string, dll)
```python

for i in range(3):

print(i) # Output: 0, 1, 2

```

- **`while` loop**: Berjalan selama kondisi bernilai `True`

```python

count = 0

while count < 3:

print(count) # Output: 0, 1, 2

count += 1

```

- **Karakteristik**:

- Mengontrol alur eksekusi

- Memiliki kondisi awal dan akhir yang jelas

- Dapat menggunakan `break` dan `continue`

---

#### **2. Iterasi (Iteration)**

- **Definisi**:

**Proses pengambilan elemen satu per satu** dari objek yang bisa
diiterasi (*iterable*).

- **Fungsi Utama**:

Mengakses elemen koleksi data secara berurutan.

- **Mekanisme di Python**:

- Menggunakan **iterator** (objek dengan metode `__iter__()` dan


`__next__()`)
- Objek iterable: list, tuple, dict, string, generator, dll

```python

buah = ["apel", "mangga", "jeruk"]

iterator = iter(buah) # Buat iterator

print(next(iterator)) # Output: "apel"

print(next(iterator)) # Output: "mangga"

```

- **Implementasi Praktis**:

```python

# For loop sebenarnya menggunakan iterasi

for item in [1, 2, 3]:

print(item) # Di balik layar: gunakan __iter__() dan __next__()

```

---

### Perbedaan Utama

| **Aspek** | **Looping** | **Iterasi**


|

|-------------------------|--------------------------------------|--------------------------------------
|

| **Hakikat** | Struktur kontrol alur program | Proses akses


elemen satu per satu |

| **Fokus** | Mekanisme pengulangan eksekusi kode | Cara


mengambil elemen dari koleksi |

| **Level Abstraksi** | Lebih tinggi (menggunakan iterasi) | Lebih


rendah (dasar dari for loop) |

| **Komponen** | Blok kode + kondisi | Iterator +


iterable |
| **Contoh Sintaks** | `for`, `while` | `iter()`, `next()`,
generator |

| **Hubungan** | Menggunakan iterasi untuk bekerja | Bagian


fundamental dari looping |

---

### Analogi Sederhana

- **Looping** seperti **tugas harian**:

_"Cuci piring 5 piring yang kotor"_

(Proses berulang dengan jumlah pasti)

- **Iterasi** seperti **cara mencuci**:

_"Ambil satu piring → cuci → letakkan di rak → ulangi"_

(Proses berurutan tiap elemen)

---

### Contoh Integrasi

```python

# Looping FOR yang menggunakan iterasi

angka = [10, 20, 30]

# Di balik layar:

iterator = iter(angka)

while True:

try:

nilai = next(iterator)

print(nilai * 2) # Output: 20, 40, 60

except StopIteration:
break

```

---

### **Kesimpulan**

- **Looping** = **"How to repeat"**

Cara mengulang eksekusi kode (struktur kontrol: `for`/`while`).

- **Iterasi** = **"How to access"**

Cara mengakses elemen dalam koleksi (mekanisme dasar via iterator).

Setiap looping menggunakan iterasi, tetapi tidak semua iterasi


membutuhkan looping (contoh: manual dengan `next()`). Iterasi adalah
konsep fundamental yang memungkinkan looping bekerja pada koleksi
data.

++++++++++++++++++++++++++++++++++

#### 4. **Control Flow Statement**

(Pernyataan Kontrol Alur: `break`, `continue`, `pass`)

- `break`: Menghentikan perulangan

```python

for num in [1, 2, 3, 4]:

if num == 3:

break # Loop berhenti di sini

print(num)

```

- `continue`: Melompati iterasi saat ini

```python

for num in [1, 2, 3, 4]:


if num == 3:

continue # Loncat ke iterasi berikutnya

print(num)

```

- `pass`: Penghias sintaks (tidak melakukan apa-apa)

```python

if kondisi_kompleks:

pass # TODO: Implementasi nanti

```

#### 5. **Function/Method Statement**

(Pernyataan Fungsi: `def`, `return`, `yield`)

- `def`: Mendefinisikan fungsi

```python

def tambah(a, b):

return a + b

```

- `return`: Mengembalikan nilai dari fungsi

- `yield`: Mengembalikan generator (fungsi generator)

#### 6. **Import Statement**

(Pernyataan Impor: `import`, `from`)

Mengimpor modul/paket.

```python

import math

from datetime import date

```

#### 7. **Exception Handling Statement**


(Pernyataan Penanganan Error: `try`, `except`, `finally`, `raise`)

```python

try:

hasil = 10 / 0

except ZeroDivisionError:

print("Tidak bisa dibagi nol!")

finally:

print("Blok cleanup")

```

#### 8. **Class Statement**

(Pernyataan Kelas: `class`)

Mendefinisikan kelas dan OOP.

```python

class Mobil:

def __init__(self, merek):

[Link] = merek

```

#### 9. **Context Management Statement**

(Pernyataan Manajemen Konteks: `with`)

Mengelola sumber daya (file, koneksi DB).

```python

with open("[Link]", "r") as f:

konten = [Link]()

# File otomatis ditutup di sini

```

#### 10. **Other Statements**


- `assert`: Memverifikasi kondisi (debugging)

```python

assert len(data) > 0, "Data tidak boleh kosong"

```

- `del`: Menghapus referensi objek

```python

del daftar[0] # Hapus elemen pertama

```

- `global`/`nonlocal`: Mengatur lingkup variabel

---

### **Perbedaan Statement vs Expression**

| **Statement** | **Expression** |

|-----------------------------------|------------------------------------|

| Instruksi lengkap untuk dieksekusi | Kode yang menghasilkan nilai |

| Contoh: `if x > 0: print(x)` | Contoh: `x + 5`, `func()` |

| Tidak bisa di-assign ke variabel | Bisa di-assign ke variabel |

| Sering diakhiri newline (atau `;`)| Selalu bagian dari statement |

**Contoh kombinasi**:

```python

hasil = x * 2 # "hasil = x * 2" adalah statement, "x * 2" adalah expression

```

---

### **Multi-Statement dalam Satu Baris**

Gunakan titik koma (`;`) untuk memisahkan statement:


```python

a = 1; b = 2; print(a + b) # 3 statement dalam 1 baris

```

> **Catatan**: Praktik ini umumnya dihindari karena mengurangi


keterbacaan kode.

---

### **Compound Statement**

Statement yang mengandung blok kode (didefinisikan dengan indentasi):

```python

if kondisi: # Header statement

# Blok statement

print("Benar")

x = 10

```

---

### **Kenali Statement dengan `ast` Module**

Modul `ast` (Abstract Syntax Tree) membantu menganalisis struktur


statement:

```python

import ast

kode = """

def sapa(nama):

print("Halo", nama)

"""
tree = [Link](kode)

print([Link](tree, indent=2))

```

---

### **Kesimpulan**

- **Statement** = Perintah aksi dalam program

- **Expression** = Bagian dari statement yang menghasilkan nilai

- Program Python adalah kumpulan statement yang dieksekusi secara


berurutan

- Pemahaman jenis-jenis statement penting untuk mengontrol alur


program dan logika aplikasi

> "Statement adalah tulang punggung program: mereka menentukan apa


yang dilakukan, kapan, dan bagaimana."

- **Indentasi (Indentation)**

### **Indentation (Indentasi) dalam Python**

**Indentasi** adalah **penggunaan spasi atau tab di awal baris kode**


untuk menunjukkan **tingkat hierarki blok kode** dalam Python. Berbeda
dengan bahasa pemrograman lain yang menggunakan tanda kurung `{}`
untuk mendefinisikan blok, Python menggunakan indentasi sebagai
bagian dari sintaksisnya.

---

#### **Mengapa Indentasi Penting di Python?**

1. **Penentu Struktur Blok Kode**


Python menggunakan indentasi untuk mengetahui awal dan akhir blok
kode (seperti fungsi, percabangan, perulangan).

2. **Wajib Secara Sintaksis**

Kesalahan indentasi akan menyebabkan `IndentationError` dan program


gagal dieksekusi.

3. **Meningkatkan Keterbacaan**

Kode otomatis lebih rapi dan mudah dibaca.

---

#### **Aturan Dasar Indentasi**

1. **Gunakan Spasi atau Tab Secara Konsisten**

- Rekomendasi PEP 8: **4 spasi** per tingkat indentasi.

- Jangan mencampur spasi dan tab dalam satu file!

2. **Blok Kode Dimulai Setelah Tanda Titik Dua (`:`)**

Contoh:

```python

if kondisi: # Tanda : menandakan awal blok

print("Ini dalam blok if") # Di-indentasi 4 spasi

print("Masih dalam blok if")

```

3. **Tingkat Indentasi Harus Sama untuk Satu Blok**

```python

for i in range(3):

print(i) ✅ Benar

print(i*2) ❌ Salah (IndentationError)

```
---

#### **Contoh Praktis**

**1. Percabangan (`if-elif-else`)**

```python

umur = 18

if umur < 13:

print("Anak-anak") # Blok if

elif umur < 20:

print("Remaja") # Blok elif

else:

print("Dewasa") # Blok else

```

**2. Perulangan (`for`, `while`)**

```python

for i in range(3):

print("Luar:", i) # Blok for

for j in range(2):

print("Dalam:", j) # Blok for bersarang (indentasi ganda)

```

**3. Fungsi (`def`)**

```python

def sapa(nama):

print("Halo,", nama) # Blok fungsi

return len(nama) # Masih dalam blok yang sama

```
**4. Konteks (`with`)**

```python

with open("[Link]") as f:

data = [Link]() # Blok konteks

print(data) # Masih dalam blok

```

---

#### **Kesalahan Umum**

1. **Indentasi Tidak Konsisten**

```python

if True:

print("4 spasi") # ❌

print("8 spasi") # ❌ IndentationError

```

2. **Lupa Indentasi Setelah `:`**

```python

if True:

print("Error!") # ❌ IndentationError

```

3. **Indentasi Tanpa Perlu**

```python

print("Hello")

print("Dunia") # ❌ Unexpected indent

```
---

#### **Best Practices (PEP 8)**

1. **Gunakan 4 spasi per indentasi** (jangan pakai tab).

2. **Editor Konfigurasi**:

- Aktifkan pengaturan "convert tabs to spaces" di editor Anda.

- Gunakan shortcut editor untuk indentasi otomatis.

3. **Hindari Baris Kosong dengan Indentasi**:

```python

def contoh():

print("Baris pertama")

# ❌ Baris kosong ber-indentasi

print("Baris kedua")

```

---

#### **Cara Mengecek Indentasi**

1. **Aktifkan Visible Whitespace** di editor untuk melihat spasi/tab:

![Indentasi terlihat sebagai titik atau


panah]([Link]

2. **Gunakan Linter** seperti `flake8` atau `pylint` yang akan memberi


tahu kesalahan indentasi.

---

### **Mengapa Python Menggunakan Indentasi?**

- **Filosofi Python**: "Readability counts" (Keterbacaan adalah prioritas).


- **Memaksa Penulisan Kode Rapi**: Tidak ada perdebatan gaya kurung
`{}`.

- **Mengurangi Bug**: Blok kode yang jelas mengurangi kesalahan logika.

> 💡 **Fun Fact**:

> Indentasi adalah alasan utama mengapa kode Python terlihat bersih
dan elegan dibanding bahasa lain!

---

### **Kesimpulan**

Indentasi di Python bukan sekadar gaya penulisan, tapi **syarat sintaksis


wajib** yang:

- Menentukan struktur blok kode

- Meningkatkan konsistensi dan keterbacaan

- Mencegah kesalahan logika

Dengan mengikuti aturan 4 spasi per tingkat, kode Anda akan lebih
profesional dan bebas error!

- **Dokumentasi (Docstrings)**

### **Docstrings dalam Python**

**Docstrings** (documentation strings) adalah string literal khusus yang


berfungsi sebagai **dokumentasi resmi** untuk modul, fungsi, kelas, atau
metode dalam Python. Berbeda dengan komentar biasa, docstrings
disimpan sebagai atribut `__doc__` dan dapat diakses secara terprogram.

---

#### **Ciri Khas Docstrings**

1. **Diawali dan diakhiri triple quotes** (`"""` atau `'''`)


2. **Posisi strategis**:

- Baris pertama setelah `def` (fungsi)

- Baris pertama setelah `class` (kelas)

- Di awal file (modul)

3. **Bisa multi-baris** dengan struktur terformat

---

#### **Contoh Sederhana**

```python

def tambah(a, b):

"""Menambahkan dua bilangan."""

return a + b

```

---

### **Fungsi & Manfaat Docstrings**

1. **Dokumentasi Otomatis**

Bisa diakses via `help()` atau IDE.

2. **Introspection**

Diakses runtime melalui `objek.__doc__`.

3. **Panduan Penggunaan**

Menjelaskan parameter, return value, dan perilaku.

4. **Dukungan Tools**

Digunakan generator dokumentasi seperti Sphinx.

---
### **Struktur Docstring (PEP 257)**

#### Format Standar:

```python

def fungsi(parameter):

"""

Deskripsi singkat (1 baris).

Deskripsi detail (opsional).

Parameters:

- parameter (tipe): Deskripsi

Returns:

tipe: Deskripsi nilai kembalian

"""

```

---

#### **Contoh Lengkap**

```python

def hitung_rata_rata(angka):

"""

Menghitung rata-rata list angka.

Parameters:

angka (list[float]): List berisi angka

Returns:
float: Nilai rata-rata

Raises:

ValueError: Jika list kosong

"""

if len(angka) == 0:

raise ValueError("List tidak boleh kosong")

return sum(angka) / len(angka)

```

---

### **Jenis Docstrings**

1. **Satu Baris**

Untuk fungsi sederhana

```python

def kuadrat(x):

"""Mengembalikan kuadrat dari x."""

return x * x

```

2. **Multi-Baris**

Untuk fungsi/kelas kompleks

```python

class Karyawan:

"""Representasi objek karyawan.

Attributes:

nama (str): Nama lengkap


gaji (int): Gaji per bulan

"""

```

---

### **Cara Mengakses Docstrings**

1. Menggunakan `help()`:

```python

help(hitung_rata_rata)

```

Output:

```

hitung_rata_rata(angka)

Menghitung rata-rata list angka.

Parameters:

angka (list[float]): List berisi angka

...

```

2. Menggunakan `__doc__`:

```python

print(hitung_rata_rata.__doc__)

```

3. **IDE Support**:

Docstrings muncul otomatis di VSCode, PyCharm, dll.

![Contoh tampilan docstring di IDE]([Link]


---

### **Standar Format Docstrings**

| **Style** | **Ciri Khas** | **Contoh**


|

|-----------------|----------------------------------------|------------------------------------------|

| **reST** | Format default Sphinx | `:param angka:


Deskripsi` |

| **Google** | Ringkas, populer di komunitas | `Args: \n angka


(list): Deskripsi` |

| **NumPy/SciPy** | Detail, mirip LaTeX | `Parameters \n


---------- \n angka : list` |

| **Epytext** | Sintaks seperti Javadoc | `@param angka:


Deskripsi` |

Contoh Google Style:

```python

def bagi(dividen, pembagi):

"""Melakukan pembagian dua bilangan.

Args:

dividen (float): Bilangan yang dibagi

pembagi (float): Pembagi

Returns:

float: Hasil pembagian

Raises:

ZeroDivisionError: Jika pembagi nol

"""
```

---

### **Docstrings untuk Konteks Lain**

1. **Modul**

```python

"""Modul utilitas matematika.

Berisi fungsi-fungsi perhitungan dasar.

Versi: 1.0.0

"""

```

2. **Kelas**

```python

class Persegi:

"""Mewakili bentuk persegi.

Attributes:

sisi (float): Panjang sisi persegi

"""

```

3. **Package**

Di file `__init__.py`:

```python

"""Package operasi database.


Berisi modul:

- koneksi: Manajemen koneksi DB

- query: Eksekusi SQL

"""

```

---

### **Best Practices (PEP 257)**

1. **Baris pertama** = ringkasan singkat (≤ 1 baris)

2. **Baris kosong** setelah ringkasan untuk multi-baris

3. **Deskripsi parameter**:

- Nama parameter

- Tipe data

- Penjelasan

4. **Konsisten** dalam satu proyek

5. **Bahasa Inggris** untuk proyek kolaboratif

---

### **Perbedaan Docstring vs Komentar**

| **Docstrings** | **Komentar** |

|------------------------------------|----------------------------------|

| Untuk dokumentasi eksternal | Untuk penjelasan internal |

| Diakses via `help()` dan `__doc__` | Tidak disimpan di runtime |

| Format terstruktur | Bebas tanpa struktur |

| Hanya di lokasi spesifik | Bisa di mana saja dalam kode |

---
### **Tools Pendukung**

1. **Sphinx**: Generator dokumentasi profesional

2. **pydoc**: Modul bawaan Python (`python -m pydoc`)

3. **doctest**: Jalankan test case dalam docstring

```python

def tambah(a, b):

"""Contoh doctest:

>>> tambah(2, 3)

"""

return a + b

```

---

### **Kesimpulan**

Docstrings adalah **dokumentasi hidup** yang:

- Menjelaskan cara pakai fungsi/kelas

- Meningkatkan maintainability kode

- Memungkinkan dokumentasi otomatis

- Menjadi kontrak antara developer dan pengguna

> 💡 **Pepatah Python**:

> *"Code is more often read than written. Docstrings make reading a
pleasure."*

-----------------------------------------------------------------------

#### **2. Variabel & Penugasan**


- **Penugasan Variabel (Variable Assignment)**

### **Variabel Assignment dalam Python**

Variabel assignment adalah proses **menetapkan nilai ke sebuah nama


variabel** dalam Python. Ini adalah konsep fundamental yang
memungkinkan Anda menyimpan dan mengelola data dalam kode.

#### **Struktur Dasar:**

```python

nama_variabel = nilai

```

- **`nama_variabel`**: Nama yang Anda berikan untuk merujuk ke data.

- **`=`**: Operator assignment (tanda sama dengan).

- **`nilai`**: Data yang disimpan (angka, teks, list, dll).

---

### **Contoh Sederhana:**

```python

umur = 25

nama = "Budi"

gaji = 7500.00

is_active = True

```

---

### **Karakteristik Penting:**

1. **Dynamic Typing**

Python otomatis menetapkan tipe data berdasarkan nilai yang diberikan.


```python

x = 10 # x bertipe integer

x = "halo" # x sekarang bertipe string

```

2. **Case-Sensitive**

Nama variabel bersifat sensitif terhadap huruf besar/kecil.

```python

nama ≠ Nama ≠ NAMA # Tiga variabel berbeda!

```

3. **Assignment Bukan Copy**

Ketika Anda mengassign variabel ke variabel lain, keduanya merujuk ke


objek yang sama di memori.

```python

a = [1, 2, 3]

b=a

[Link](4)

print(a) # Output: [1, 2, 3, 4] (a ikut berubah!)

```

---

### **Teknik Assignment Lanjutan:**

1. **Multiple Assignment**

Menetapkan banyak variabel sekaligus dalam satu baris.

```python

x, y, z = 10, 20, 30

```
2. **Chained Assignment**

Menetapkan nilai yang sama ke beberapa variabel.

```python

a = b = c = 100

```

3. **Unpacking**

Menetapkan elemen dari struktur data (seperti list/tuple) ke variabel


terpisah.

```python

data = ["apel", 12, 3.5]

buah, jumlah, harga = data

```

4. **Augmented Assignment**

Memodifikasi nilai variabel dengan operator singkat.

```python

total = 5

total += 3 # Sama dengan total = total + 3 → total jadi 8

```

---

### **Aturan Penamaan Variabel:**

- Harus dimulai dengan huruf atau underscore (`_`).

- Hanya boleh berisi huruf, angka, dan underscore.

- Tidak boleh menggunakan [keyword


Python]([Link]
ds) seperti `if`, `for`, `while`, dll.
```python

# Contoh valid

nama_mahasiswa = "Ali"

_counter = 0

nilai1 = 85.5

# Contoh tidak valid

2jenis = "A" # Error: Diawali angka

if = "kondisi" # Error: Pakai keyword

```

---

### **Best Practices:**

1. Gunakan nama yang deskriptif:

```python

# Buruk

x = 100

# Baik

max_speed = 100

```

2. Gunakan snake_case untuk penamaan:

```python

jumlah_barang = 10 # (bukan jumlahBarang)

```

3. Hindari nama terlalu panjang:


```python

# Buruk

jumlah_total_produk_yang_dibeli_pada_hari_ini = 50

# Baik

total_produk_hari_ini = 50

```

---

### **Contoh Kasus Nyata:**

```python

# Hitung luas segitiga

alas = 10

tinggi = 5

luas = 0.5 * alas * tinggi

print(f"Luas segitiga: {luas}") # Output: Luas segitiga: 25.0

# Update nilai

tinggi += 2 # Tinggi menjadi 7

luas = 0.5 * alas * tinggi

print(f"Luas baru: {luas}") # Output: Luas baru: 35.0

```

Intinya: **Variabel assignment adalah cara Python untuk "mengingat"


nilai/data agar bisa digunakan kembali dalam program.** 🧠💡

- **Penugasan Berganda (Multiple Assignments)**

### **Multiple Assignments dalam Python**


Multiple assignments (atau *tuple unpacking*) adalah teknik di Python
yang memungkinkan Anda **menetapkan nilai ke beberapa variabel
sekaligus dalam satu baris kode**. Ini membuat kode lebih ringkas,
mudah dibaca, dan efisien.

---

#### **Contoh Dasar:**

```python

# Menetapkan nilai ke tiga variabel sekaligus

x, y, z = 10, 20, 30

print(x) # Output: 10

print(y) # Output: 20

print(z) # Output: 30

```

---

### **4 Jenis Multiple Assignments:**

1. **Standard Multiple Assignment**

Menetapkan nilai berbeda ke beberapa variabel:

```python

nama, umur, pekerjaan = "Budi", 25, "Insinyur"

```

2. **Pertukaran Nilai (Swap)**

Menukar nilai antar variabel tanpa variabel sementara:


```python

a, b = 5, 10

a, b = b, a # Pertukaran nilai

print(a) # Output: 10

print(b) # Output: 5

```

3. **Unpacking Struktur Data**

Mengekstrak elemen dari list/tuple ke variabel terpisah:

```python

koordinat = [12.5, -7.8]

x, y = koordinat # x = 12.5, y = -7.8

```

4. **Unpacking dengan Asterisk (`*`)**

Menangkap beberapa elemen dalam satu variabel (biasanya untuk sisa


elemen):

```python

first, *middle, last = [1, 2, 3, 4, 5]

print(first) # 1

print(middle) # [2, 3, 4]

print(last) # 5

```

---

### **Aturan Penting:**

1. **Jumlah Harus Sama**

Jumlah variabel di kiri harus sama dengan jumlah nilai di kanan:


```python

# Benar

a, b, c = 1, 2, 3

# Salah (akan error)

x, y = 10, 20, 30 # ValueError: too many values to unpack

```

2. **Unpacking dengan `*` Fleksibel**

Asterisk (`*`) bisa digunakan untuk menangkap sisa elemen berapa pun:

```python

start, *rest = [10, 20, 30, 40] # rest = [20, 30, 40]

```

3. **Ignoring Values**

Gunakan underscore (`_`) untuk mengabaikan nilai yang tidak


diperlukan:

```python

nama, _, gaji = ("Lisa", "HRD", 8000) # Abaikan jabatan

```

---

### **Contoh Praktis:**

#### 1. **Membaca Data dari Fungsi**

```python

# Fungsi mengembalikan multiple values

def hitung_luas_keliling(panjang, lebar):


luas = panjang * lebar

keliling = 2 * (panjang + lebar)

return luas, keliling # Kembalikan sebagai tuple

# Terima hasil dengan multiple assignment

luas, keliling = hitung_luas_keliling(5, 3)

print(f"Luas: {luas}, Keliling: {keliling}")

```

#### 2. **Iterasi Dictionary**

```python

person = {"nama": "Dewi", "umur": 28, "kota": "Jakarta"}

# Unpack key-value sekaligus

for key, value in [Link]():

print(f"{key}: {value}")

```

#### 3. **Parsing Data dari File**

```python

data_baris = "B001, Laptop, 12000000"

# Pisahkan langsung ke variabel

kode, nama_produk, harga = data_baris.split(",")

harga = int(harga) # Konversi ke integer

```

---
### **Kapan Menggunakan Multiple Assignments?**

1. Ketika bekerja dengan fungsi yang mengembalikan banyak nilai

2. Saat menukar nilai antar variabel

3. Untuk mengurai struktur data kompleks

4. Ketika ingin mengabaikan nilai tertentu (dengan `_`)

5. Untuk membuat kode lebih Pythonic dan ringkas

> 💡 **Tip**: Multiple assignments sebenarnya adalah bentuk *tuple


unpacking*. Sintaks `x, y = 1, 2` setara dengan `(x, y) = (1, 2)`.

-----------------------------------------------------------------------

#### **3. Tipe Data**

- **Numerik (Numeric)**

### **Numeric dalam Python**

**Numeric** (atau tipe data numerik) dalam Python adalah tipe data yang
digunakan untuk merepresentasikan **nilai-nilai angka**. Python
mendukung beberapa jenis tipe data numerik bawaan (*built-in*) yang
dikelompokkan menjadi tiga kategori utama:

---

### **1. Integer (`int`)**

- **Deskripsi**: Bilangan bulat (tanpa desimal).

- **Rentang**: Tidak terbatas (hanya tergantung memori sistem).

- **Contoh**:

```python

a=5 # Positif

b = -10 # Negatif
c = 1_000_000 # Penulisan dengan underscore untuk keterbacaan (1
juta)

```

### **2. Float (`float`)**

- **Deskripsi**: Bilangan desimal (presisi tunggal/ganda).

- **Rentang**: Sekitar ±1.8e308 (tergantung sistem).

- **Contoh**:

```python

d = 3.14 # Desimal positif

e = -0.001 # Desimal negatif

f = 2.5e-3 # Notasi ilmiah (0.0025)

```

### **3. Complex (`complex`)**

- **Deskripsi**: Bilangan kompleks (bentuk `a + bj`).

- **Komponen**:

- `a`: Bagian real

- `b`: Bagian imajiner

- `j`: Unit imajiner (√-1)

- **Contoh**:

```python

g = 4 + 2j # Bilangan kompleks

h = complex(3, -5) # 3 - 5j

```

---

### **Operasi Numerik Dasar**


| Operasi | Simbol | Contoh | Hasil |

|---------|--------|--------|-------|

| Penjumlahan | `+` | `5 + 3` | `8` |

| Pengurangan | `-` | `10 - 4` | `6` |

| Perkalian | `*` | `3 * 2.5` | `7.5` |

| Pembagian | `/` | `10 / 3` | `3.333...` |

| Pembagian Bulat | `//` | `10 // 3` | `3` |

| Modulus | `%` | `10 % 3` | `1` |

| Pangkat | `**` | `2 ** 4` | `16` |

---

### **Konversi Tipe Numerik**

Python memungkinkan konversi antar tipe numerik:

```python

x=5 # int

y = float(x) # 5.0 (float)

z = complex(x) # (5+0j) (complex)

# Konversi string ke numerik

a = int("100") # 100 (int)

b = float("3.14") # 3.14 (float)

```

---

### **Modul Pendukung Numerik**

1. **`math`**: Fungsi matematika dasar

```python
import math

print([Link](25)) # 5.0 (akar kuadrat)

print([Link](5)) # 120

```

2. **`cmath`**: Fungsi untuk bilangan kompleks

```python

import cmath

print([Link](1+1j)) # 0.785... (radian)

```

3. **`decimal`**: Presisi desimal tinggi (untuk keuangan)

```python

from decimal import Decimal

total = Decimal("0.1") + Decimal("0.2") # 0.3 (bukan


0.30000000000000004)

```

4. **`fractions`**: Bilangan pecahan

```python

from fractions import Fraction

frac = Fraction(3, 4) # 3/4

```

---

### **Perilaku Unik Numerik di Python**

1. **Pembagian Otomatis ke Float**:

```python
print(10 / 2) # 5.0 (bukan 5)

```

2. **Integer Tidak Terbatas**:

```python

big_num = 10**1000 # Valid (1 diikuti 1000 nol)

```

3. **Underflow/Overflow Float**:

```python

print(1e500) # Overflow → inf

print(1e-500) # Underflow → 0.0

```

---

### **Contoh Praktis**

```python

# Hitung luas lingkaran

radius = 7

pi = 3.14159

luas = pi * radius ** 2

print(f"Luas lingkaran: {luas:.2f}") # Format 2 desimal

# Konversi suhu Celcius ke Fahrenheit

celcius = 25

fahrenheit = (celcius * 9/5) + 32

print(f"25°C = {fahrenheit}°F")

```
**Output**:

```

Luas lingkaran: 153.94

25°C = 77.0°F

```

### **Kesimpulan**

Tipe data numerik (`int`, `float`, `complex`) adalah fondasi penting dalam
pemrograman Python untuk:

- Perhitungan matematika

- Pemrosesan data

- Algoritma sains

- Aplikasi keuangan

- Dan banyak lagi!

Python menyediakan fleksibilitas dan dukungan luas melalui operator


bawaan dan modul pendukung.

- **Boolean (Boolean)**

### **Boolean dalam Python**

**Boolean** adalah tipe data yang merepresentasikan dua nilai


kebenaran:

- `True` (Benar)

- `False` (Salah)

Boolean merupakan dasar dari logika pemrograman dan pengambilan


keputusan dalam Python. Tipe ini adalah subtipe dari `int`, di mana `True
= 1` dan `False = 0`.
---

### **Cara Kerja Boolean**

#### 1. **Ekspresi Logika**

Hasil operasi perbandingan/lojik selalu menghasilkan boolean:

```python

umur = 20

print(umur >= 18) # True (benar)

print(5 == "5") # False (salah)

```

#### 2. **Truthy dan Falsy**

Python mengonversi nilai non-boolean ke boolean secara implisit:

- **Falsy** (dianggap `False`):

`0`, `""` (string kosong), `[]` (list kosong), `None`, `{}`, `()`

- **Truthy** (dianggap `True`):

Semua nilai lain (angka ≠0, string berisi teks, struktur data tidak kosong)

```python

print(bool(0)) # False

print(bool("Hi")) # True

print(bool([])) # False

```

#### 3. **Operasi Boolean**

| Operator | Deskripsi | Contoh |

|----------|-----------|--------|

| `and` | Benar jika KEDUANYA benar | `True and False → False` |

| `or` | Benar jika SALAH SATU benar | `True or False → True` |


| `not` | Membalik nilai boolean | `not True → False` |

---

### **Contoh Praktis**

#### 1. Validasi Input

```python

email = "user@[Link]"

password = "secret123"

# Cek kebenaran dua kondisi

is_valid = (email != "") and (len(password) >= 8)

print(is_valid) # True

```

#### 2. Pengendalian Alur Program

```python

saldo = 5000

tarik = 3000

# Gunakan boolean dalam percabangan

if saldo >= tarik:

print("Penarikan berhasil")

else:

print("Saldo tidak mencukupi")

```

#### 3. Filter Data

```python
angka = [15, 0, 8, -4, 0, 9]

# Filter nilai truthy (≠0)

hasil = list(filter(bool, angka))

print(hasil) # [15, 8, -4, 9]

```

---

### **Fungsi Bawaan Boolean**

1. **`bool()`**

Konversi nilai ke boolean:

```python

print(bool(10)) # True

print(bool(None)) # False

```

2. **`isinstance()`**

Cek tipe data boolean:

```python

flag = True

print(isinstance(flag, bool)) # True

```

---

### **Kasus Khusus**

1. **Perhitungan Aritmatika**

Boolean bisa dioperasikan seperti angka:


```python

print(True + True) # 2 (1+1)

print(False * 10) #0

```

2. **Perbandingan Berantai**

Kombinasi beberapa perbandingan:

```python

x=5

print(3 < x < 10) # True (3<5 dan 5<10)

```

---

### **Best Practice**

1. **Hindari perbandingan redundant**

```python

# Buruk

if is_active == True:

# Baik

if is_active:

```

2. **Gunakan operator logika untuk penyederhanaan**

```python

# Daripada:

if x > 0:

if y > 0:
# Gunakan:

if x > 0 and y > 0:

```

---

### **Diagram Logika Boolean**

```

Input A Input B A AND B A OR B

-------------------------------------------------

True True True True

True False False True

False True False True

False False False False

```

Boolean adalah **fondasi logika** dalam Python yang mengontrol:

- Percabangan (`if/else`)

- Perulangan (`while`)

- Validasi data

- Alur program kompleks

Pemahaman boolean yang baik = kunci membangun logika program yang


efektif! 🔑

- **String**

- Pembuatan String

### **Pembuatan String dalam Python**


String adalah deretan karakter (teks) yang merupakan salah satu tipe
data fundamental dalam Python. Pembuatan string dilakukan dengan
beberapa cara fleksibel:

---

#### **1. Menggunakan Tanda Kutip**

Python mendukung tiga jenis tanda kutip:

```python

# Kutip tunggal

s1 = 'Hello World'

# Kutip ganda

s2 = "Python Programming"

# Kutip tiga (multi-line)

s3 = '''Ini adalah

string multi-baris

di Python'''

```

#### **2. Escape Characters**

Karakter khusus dimulai dengan backslash (`\`):

```python

pesan = "Baris pertama\nBaris kedua" # \n = newline

path = "C:\\Folder\\[Link]" # \\ = backslash

kutip = "Dia berkata, \"Halo!\"" # \" = kutip ganda

```

#### **3. Raw Strings (r-string)**


Abaikan karakter escape:

```python

raw_path = r"C:\Folder\[Link]" # Output: C:\Folder\[Link]

```

#### **4. f-Strings (Formatted Strings)**

Menyisipkan ekspresi/variabel (Python 3.6+):

```python

nama = "Budi"

umur = 25

sapa = f"Halo, {nama}! Usia Anda {umur} tahun."

# Output: Halo, Budi! Usia Anda 25 tahun.

```

#### **5. Konversi ke String**

Menggunakan fungsi `str()`:

```python

angka = 42

teks = str(angka) # "42"

```

---

### **Operasi Dasar String**

| Operasi | Contoh | Hasil |

|---------|--------|-------|

| Penggabungan | `"Py" + "thon"` | `"Python"` |

| Perulangan | `"A" * 3` | `"AAA"` |

| Indexing | `"Python"[0]` | `"P"` |


| Slicing | `"Python"[2:4]` | `"th"` |

| Panjang | `len("Python")` | `6` |

---

### **Metode String Penting**

```python

text = " hello Python! "

# Case conversion

print([Link]()) # " HELLO PYTHON! "

print([Link]()) # " hello python! "

print([Link]()) # " Hello Python! "

# Whitespace handling

print([Link]()) # "hello Python!"

# Search/replace

print([Link]("Py")) # 7 (posisi substring)

print([Link]("h", "H")) # " Hello Python! "

# Check content

print([Link](" ")) # True

print("123".isdigit()) # True

```

---

### **String Multibahasa & Unicode**


Python 3 menggunakan Unicode secara default:

```python

jepang = "こんにちは" # Halo dalam bahasa Jepang

emoji = "Python 🐍" # String dengan emoji

```

---

### **Perbandingan Teknik Pembuatan String**

| Teknik | Use Case | Kelebihan |

|--------|----------|-----------|

| `f""` | Format dinamis | Mudah baca, ekspresi langsung |

| `str()` | Konversi nilai | Ubah angka/objek ke teks |

| `r""` | Path/Regex | Hindari masalah escape |

| `"""` | Teks multi-baris | Pertahankan line breaks |

---

### **Contoh Praktis**

```python

# Format string untuk laporan

nama = "Lisa"

saldo = 1250000

laporan = f"""

Laporan Nasabah:

Nama: {nama}

Saldo: Rp{saldo:,}

Terakhir diperbarui: {[Link]():%d/%m/%Y}

"""
print(laporan)

```

**Output**:

```

Laporan Nasabah:

Nama: Lisa

Saldo: Rp1,250,000

Terakhir diperbarui: 15/07/2023

```

---

### **Best Practices**

1. Gunakan **f-string** untuk format modern (Python 3.6+)

2. **Raw string** untuk regex/path Windows

3. **Triple quotes** untuk docstrings dan teks panjang

4. Hindari `+` untuk penggabungan banyak string (gunakan `.join()`)

```python

# Tidak efisien

hasil = ""

for kata in ["A", "B", "C"]:

hasil += kata # Membuat string baru tiap iterasi

# Lebih efisien

kata_list = ["A", "B", "C"]

hasil = "".join(kata_list)

```
String di Python mendukung **immutability** - sekali dibuat, isinya tidak
bisa diubah. Operasi string selalu menghasilkan string baru!

- Pengindeksan:

- Indeks Maju (Forward Indexing)

### **Indeks Maju (Forward Indexing) dalam Python**

Indeks maju adalah metode pengaksesan elemen dalam struktur data


sekuensial (seperti string, list, atau tuple) **dari awal ke akhir**
menggunakan penomoran positif yang dimulai dari **0** untuk elemen
pertama.

---

#### **Konsep Dasar:**

| Struktur Data | Urutan Elemen | Indeks Maju |

|---------------|---------------|-------------|

| `"Python"` | `['P','y','t','h','o','n']` | `0,1,2,3,4,5` |

| `[10,20,30]` | `[10,20,30]` | `0,1,2` |

```python

s = "Python"

print(s[0]) # 'P' → Elemen pertama

print(s[2]) # 't' → Elemen ketiga

```

---

#### **Karakteristik Indeks Maju:**

1. **Dimulai dari 0**


Elemen pertama selalu di indeks `0`

2. **Meningkat Berurutan**

Setiap elemen berikutnya +1

3. **Akses Langsung**

Menggunakan notasi `[indeks]`

4. **Mendukung Slicing**

Format: `[start:stop:step]`

---

#### **Contoh Operasi:**

**1. Akses Elemen Tunggal**

```python

word = "Python"

print(word[0]) # P

print(word[3]) # h

```

**2. Slicing (Pemotongan)**

```python

numbers = [10, 20, 30, 40, 50]

# Ambil elemen indeks 1 sampai 3 (eksklusif)

print(numbers[1:3]) # [20, 30]


# Ambil dari awal hingga indeks 2

print(numbers[:3]) # [10, 20, 30]

# Ambil setiap elemen ke-2

print(numbers[::2]) # [10, 30, 50]

```

**3. Iterasi dengan Indeks**

```python

fruits = ["Apel", "Mangga", "Jeruk"]

for i in range(len(fruits)):

print(f"Buah ke-{i}: {fruits[i]}")

```

**Output:**

```

Buah ke-0: Apel

Buah ke-1: Mangga

Buah ke-2: Jeruk

```

---

### **Perbandingan: Indeks Maju vs Mundur**

| Fitur | Indeks Maju | Indeks Mundur |

|-------|-------------|---------------|

| **Arah** | Awal → Akhir | Akhir → Awal |

| **Start** | `0` (elemen pertama) | `-1` (elemen terakhir) |


| **Contoh** | `[0][1][2]` | `[-3][-2][-1]` |

| **Slicing** | `[0:3]` | `[-3:]` |

---

### **Error Umum:**

```python

text = "Hi"

print(text[2]) # IndexError: string index out of range

```

**Solusi:** Cek panjang objek dengan `len()` sebelum mengakses indeks:

```python

if len(text) > 2:

print(text[2])

```

---

### **Best Practices:**

1. Gunakan `enumerate()` untuk iterasi + indeks:

```python

for idx, buah in enumerate(fruits):

print(f"{idx}: {buah}")

```

2. Hindari hardcode indeks:

```python

# Tidak disarankan

first = data[0]
last = data[4] # Asumsi salah panjang data

# Lebih aman

first = data[0]

last = data[-1] # Selama data tidak kosong

```

---

### **Diagram Visual Indeks Maju:**

```

P y t h o n → String

[0] [1] [2] [3] [4] [5] Indeks Maju

↑ ↑ ↑ ↑ ↑ ↑

Elemen 1 2 3 4 5 6

```

Indeks maju adalah metode **paling fundamental** dalam Python untuk


bekerja dengan data sekuensial. Pemahaman solid tentang konsep ini
penting untuk manipulasi string, list, dan struktur data lainnya!

- Indeks Mundur (Backward Indexing)

### **Indeks Mundur (Negative Indexing) dalam Python**

Indeks mundur adalah metode pengaksesan elemen dalam struktur data


sekuensial (seperti string, list, atau tuple) **dari akhir ke awal**
menggunakan penomoran negatif. Elemen terakhir memiliki indeks `-1`,
elemen kedua dari akhir `-2`, dan seterusnya.

---
#### **Konsep Dasar:**

| Struktur Data | Urutan Elemen | Indeks Mundur |

|---------------|---------------|---------------|

| `"Python"` | `['P','y','t','h','o','n']` | `-6,-5,-4,-3,-2,-1` |

| `[10,20,30]` | `[10,20,30]` | `-3,-2,-1` |

```python

s = "Python"

print(s[-1]) # 'n' → Elemen terakhir

print(s[-3]) # 'h' → Elemen ketiga dari akhir

```

---

#### **Karakteristik Indeks Mundur:**

1. **Dimulai dari -1**

Elemen terakhir selalu di indeks `-1`

2. **Menurun Berurutan**

Setiap elemen sebelumnya bernilai lebih negatif (`-2`, `-3`, dst)

3. **Akses Langsung**

Menggunakan notasi `[indeks_negatif]`

4. **Mendukung Slicing**

Format: `[start:stop:step]` dengan nilai negatif

---
#### **Contoh Operasi:**

**1. Akses Elemen Tunggal**

```python

word = "Python"

print(word[-1]) # n (elemen terakhir)

print(word[-3]) # h (elemen ketiga dari akhir)

```

**2. Slicing (Pemotongan)**

```python

numbers = [10, 20, 30, 40, 50]

# Ambil dua elemen terakhir

print(numbers[-2:]) # [40, 50]

# Ambil dari indeks -4 hingga -2 (eksklusif)

print(numbers[-4:-1]) # [20, 30, 40]

# Ambil dari awal hingga elemen ketiga dari akhir

print(numbers[:-2]) # [10, 20, 30]

```

**3. Iterasi Terbalik**

```python

text = "Python"

for i in range(-1, -len(text)-1, -1):

print(text[i], end=" ") # Output: n o h t y P

```
---

### **Perbandingan: Indeks Maju vs Mundur**

| Fitur | Indeks Maju | Indeks Mundur |

|-------|-------------|---------------|

| **Arah** | Awal → Akhir | Akhir → Awal |

| **Elemen Pertama** | `0` | `-len(objek)` |

| **Elemen Terakhir** | `len(objek)-1` | `-1` |

| **Contoh Slicing** | `[0:3]` | `[-3:]` |

---

### **Diagram Visual:**

```

P y t h o n → String

[-6][-5][-4][-3][-2][-1] Indeks Mundur

↑ ↑ ↑ ↑ ↑ ↑

Elemen 6 5 4 3 2 1 (dari akhir)

```

---

### **Kombinasi Indeks Maju-Mundur:**

```python

data = ["a", "b", "c", "d", "e"]

# Ambil elemen kedua (b) hingga kedua dari akhir (d)

print(data[1:-1]) # ['b', 'c', 'd']


```

---

### **Error Umum:**

```python

text = "Hi"

print(text[-3]) # IndexError: string index out of range

```

**Solusi:** Gunakan pengecekan panjang:

```python

if len(text) >= 3:

print(text[-3])

else:

print("String terlalu pendek")

```

---

### **Best Practices:**

1. **Akses elemen akhir tanpa `len()`**

```python

last = data[-1] # Lebih efisien daripada data[len(data)-1]

```

2. **Ambil N-elemen terakhir**

```python

last_three = data[-3:]

```
3. **Reverse dengan step negatif**

```python

reversed_data = data[::-1] # Membalik urutan

```

4. **Hindari indeks negatif di loop**

Untuk iterasi, gunakan `reversed()`:

```python

for item in reversed(data):

print(item)

```

---

### **Contoh Praktis:**

1. **Cek ekstensi file**

```python

filename = "[Link]"

if filename[-4:] == ".pdf":

print("File PDF terdeteksi")

```

2. **Proses data terbaru**

```python

sensor_readings = [23.5, 24.1, 25.0, 24.8]

latest = sensor_readings[-1] # Nilai terbaru: 24.8

```
3. **Palindrome check**

```python

def is_palindrome(word):

return word == word[::-1] # Bandingkan dengan versi terbalik

print(is_palindrome("radar")) # True

```

---

### **Kesimpulan:**

Indeks mundur adalah fitur powerful Python untuk:

- Mengakses elemen dari akhir struktur data

- Memanipulasi bagian akhir data tanpa tahu panjang pasti

- Membuat kode lebih ringkas dan ekspresif

- Mendukung operasi slicing yang fleksibel

Penguasaan indeks mundur dan maju memberi Anda kendali penuh


terhadap manipulasi data sekuensial di Python!

- Pemotongan (Slicing)

### **String Slicing dalam Python**

String slicing adalah teknik untuk **mengambil sebagian (substring) dari


sebuah string** dengan menentukan rentang indeks. Teknik ini
menggunakan notasi kurung siku (`[start:stop:step]`) untuk mengekstrak
bagian tertentu dari string.

---
#### **Format Dasar Slicing:**

```python

string[start:stop:step]

```

- **`start`**: Indeks awal (inklusif) - default: `0`

- **`stop`**: Indeks akhir (eksklusif) - default: `akhir string`

- **`step`**: Langkah/jarak pengambilan - default: `1`

---

### **Mekanisme Slicing**

```

P y t h o n → String

[0] [1] [2] [3] [4] [5] Indeks Maju

[-6][-5][-4][-3][-2][-1] Indeks Mundur

```

---

### **7 Pola Slicing Penting:**

#### 1. **Dasar**

```python

s = "Python"

# Ambil indeks 1-3 (eksklusif)

print(s[1:4]) # "yth"

# Dari awal hingga indeks 3


print(s[:4]) # "Pyth"

# Dari indeks 2 hingga akhir

print(s[2:]) # "thon"

```

#### 2. **Step Size**

```python

# Ambil setiap karakter ke-2

print(s[::2]) # "Pto"

# Ambil setiap karakter ke-2 mulai indeks 1

print(s[1::2]) # "yh"

```

#### 3. **Indeks Negatif**

```python

# Ambil 3 karakter terakhir

print(s[-3:]) # "hon"

# Ambil dari awal hingga karakter ke-3 dari akhir

print(s[:-3]) # "Pyt"

```

#### 4. **Reverse String**

```python

# Balik string dengan step -1

print(s[::-1]) # "nohtyP"

```
#### 5. **Slicing Kombinasi**

```python

# Ambil dari indeks 1 hingga 4, setiap 2 karakter

print(s[1:5:2]) # "yh"

```

#### 6. **Indeks di Luar Rentang**

Python otomatis menyesuaikan:

```python

print(s[:100]) # "Python" (berhenti di akhir string)

```

#### 7. **Step Negatif**

```python

# Dari indeks 4 ke 1 (mundur)

print(s[4:1:-1]) # "oht"

```

---

### **Visualisasi Slicing:**

```

P y t h o n

↑ ↑ ↑ ↑ ↑ ↑

0 1 2 3 4 5 → start/stop positif

-6 -5 -4 -3 -2 -1 → start/stop negatif

Contoh:
s[1:4] → "yth" (indeks 1,2,3)

s[-4:-1] → "tho" (indeks -4,-3,-2)

s[3:0:-1] → "hty" (indeks 3,2,1)

```

---

### **Kasus Khusus & Batasan:**

1. **`start` > `stop` dengan `step` positif**

Hasilnya string kosong:

```python

print(s[4:1]) # ""

```

2. **`step` = 0**

Akan error:

```python

print(s[::0]) # ValueError: slice step cannot be zero

```

3. **Slicing Tidak Mengubah String Asli**

String bersifat *immutable*:

```python

s = "Python"

s_slice = s[1:4]

print(s) # "Python" (tetap utuh)

print(s_slice) # "yth"

```
---

### **Contoh Praktis:**

#### 1. Ekstrak Domain Email

```python

email = "user@[Link]"

domain = email[[Link]("@") + 1:]

print(domain) # "[Link]"

```

#### 2. Format Nomor Telepon

```python

nomor = "081234567890"

format_nomor = f"{nomor[:4]}-{nomor[4:8]}-{nomor[8:]}"

print(format_nomor) # "0812-3456-7890"

```

#### 3. Cek Palindrome

```python

def is_palindrome(kata):

return kata == kata[::-1]

print(is_palindrome("katak")) # True

print(is_palindrome("python")) # False

```

#### 4. Parsing Tanggal

```python

tanggal = "2023-07-15"
tahun = tanggal[:4]

bulan = tanggal[5:7]

hari = tanggal[8:]

print(f"{hari}/{bulan}/{tahun}") # "15/07/2023"

```

---

### **Best Practices:**

1. Gunakan slicing daripada loop untuk operasi substring sederhana

2. Kombinasikan dengan `find()`/`index()` untuk ekstraksi dinamis

3. Manfaatkan step negatif untuk operasi reverse

4. Hindari slicing berlebihan pada string besar (gunakan generator jika


perlu)

String slicing adalah alat fundamental di Python yang memungkinkan


manipulasi teks efisien dengan sintaks ringkas. Penguasaan teknik ini
penting untuk pemrosesan data, parsing, dan transformasi teks!

- Pembaruan & Penghapusan

### **Pembaruan dan Penghapusan String dalam Python**

Di Python, string bersifat **immutable** (tidak bisa diubah). Artinya, Anda


tidak bisa mengubah karakter tertentu dalam string atau menghapus
karakter secara langsung. Namun, ada teknik khusus untuk membuat
string baru yang merupakan hasil modifikasi dari string asli.

---

### **1. Pembaruan String (Update)**


Karena string immutable, "pembaruan" dilakukan dengan membuat string
baru berdasarkan string lama.

#### **Cara Pembaruan:**

a. **Mengganti Karakter Tertentu**

Gunakan slicing + concatenation:

```python

s = "Pytbon"

# Ganti karakter ke-4 (indeks 3) dari 'b' menjadi 'h'

new_s = s[:3] + "h" + s[4:]

print(new_s) # "Python"

```

b. **Mengganti Substring**

Gunakan metode `.replace()`:

```python

text = "Saya suka Java"

updated = [Link]("Java", "Python")

print(updated) # "Saya suka Python"

```

c. **Menggunakan f-string (Python 3.6+)**

Untuk pembaruan berbasis variabel:

```python

name = "Budi"

age = 25

greeting = f"Halo, {name}! Usia Anda {age} tahun."

```
d. **Multiple Replacement**

Gunakan `[Link]()` + `.translate()`:

```python

trans_table = [Link]("aeo", "443") # a→4, e→4, o→3

text = "hello world"

print([Link](trans_table)) # "h4ll3 w3rld"

```

---

### **2. Penghapusan String (Deletion)**

Penghapusan juga membutuhkan pembuatan string baru tanpa bagian


yang ingin dihapus.

#### **Cara Penghapusan:**

a. **Menghapus Karakter Tertentu**

Gunakan slicing:

```python

s = "PyXthon" # Hapus 'X' di indeks 2

new_s = s[:2] + s[3:]

print(new_s) # "Python"

```

b. **Menghapus Substring**

Metode 1: `.replace()` (ganti dengan string kosong)

```python

text = "Data#123"

clean_text = [Link]("#", "")

print(clean_text) # "Data123"
```

Metode 2: Regular expressions (`[Link]()`)

```python

import re

text = "Hapus 123 angka"

text_no_digits = [Link](r"\d", "", text)

print(text_no_digits) # "Hapus angka"

```

c. **Menghapus Whitespace**

Gunakan metode bawaan:

```python

text = " Hello World! \t\n"

print([Link]()) # "Hello World!" (hapus ujung)

print([Link]()) # " Hello World!" (hapus kanan)

print([Link]()) # "Hello World! \t\n" (hapus kiri)

```

d. **Menghapus Karakter Spesifik**

Gunakan pemahaman daftar (list comprehension) + `join()`:

```python

text = "H@a!p#u$s%"

chars_to_remove = "@!#$%"

clean = "".join(c for c in text if c not in chars_to_remove)

print(clean) # "Hapus"

```

---
### **3. Penghapusan Variabel String**

Untuk menghapus seluruh variabel string dari memori:

```python

s = "Data sementara"

del s # Variabel s dihapus

print(s) # NameError: name 's' is not defined

```

---

### **Perbandingan Teknik**

| Tujuan | Teknik Terbaik | Contoh |

|--------|----------------|--------|

| Ganti karakter | Slicing + concat | `s[:2] + "x" + s[3:]` |

| Ganti substring | `.replace()` | `"Java".replace("J", "P")` |

| Hapus whitespace | `.strip()` | `" text ".strip()` |

| Hapus karakter acak | List comprehension | `"".join(c for c in s if c not in


"xyz")` |

| Hapus pola kompleks | `[Link]()` | `[Link](r"\d+", "", s)` |

---

### **Contoh Praktis**

#### 1. Format Nomor Telepon

```python

def format_phone(phone):

# Hapus semua non-digit

cleaned = [Link](r"\D", "", phone)


# Format: (XXX) XXX-XXXX

return f"({cleaned[:3]}) {cleaned[3:6]}-{cleaned[6:]}"

print(format_phone("Tel: 081-2345-6789")) # (081) 234-56789

```

#### 2. Sanitasi Input Pengguna

```python

user_input = " User123! "

sanitized = (user_input

.strip()

.replace("!", "")

.replace("1", "i")

.replace("2", "z")

.replace("3", "e"))

print(sanitized) # "Userize"

```

#### 3. Hapus Komentar Kode

```python

code = """

x = 5 # Inisialisasi x

y = 10 # Inisialisasi y

"""

# Hapus semua teks setelah #

clean_code = [Link](r"#.*", "", code)

print(clean_code)

# Output:

#x=5
# y = 10

```

---

### **Keterbatasan & Solusi**

1. **Immutability**

Tidak bisa mengubah string asli → selalu hasilkan string baru

2. **Performance untuk Operasi Besar**

Untuk manipulasi string besar/massal:

```python

# Tidak efisien

result = ""

for char in big_string:

if condition:

result += char # Pembuatan string baru tiap iterasi

# Lebih efisien

buffer = []

for char in big_string:

if condition:

[Link](char)

result = "".join(buffer)

```

---

### **Kesimpulan**
Meskipun Python tidak mengizinkan modifikasi string secara langsung:

- **Pembaruan**: Buat string baru dengan slicing, `.replace()`, atau f-


string

- **Penghapusan**: Buat string baru tanpa bagian yang tidak diinginkan


menggunakan slicing, `.replace()`, atau regex

- **Penghapusan variabel**: Gunakan `del` untuk menghapus referensi


string dari memori

Teknik-teknik ini memungkinkan manipulasi string yang efisien dan


ekspresif sesuai kebutuhan aplikasi!

- Penggabungan (Concatenation)

**Concatenation String** dalam Python adalah proses menggabungkan


dua atau lebih *string* menjadi satu *string* baru. Ini adalah operasi
dasar yang sering digunakan untuk membangun teks dinamis.

### Cara Melakukan Concatenation di Python:

1. **Menggunakan Operator `+`**

Contoh:

```python

s1 = "Hello"

s2 = "World"

hasil = s1 + " " + s2 # Output: "Hello World"

```

2. **Menggunakan Metode `join()`**

Efisien untuk menggabungkan banyak *string* (terutama dalam *loop*


atau *list*):

```python

kata = ["Python", "is", "powerful"]

kalimat = " ".join(kata) # Output: "Python is powerful"


```

3. **Menggunakan *f-strings* (Python 3.6+)**

Memudahkan penyisipan variabel/ekspresi:

```python

nama = "Alice"

pesan = f"Halo, {nama}!" # Output: "Halo, Alice!"

```

4. **Menggunakan Metode `format()`**

```python

a, b = "Py", "thon"

gabung = "{}{}".format(a, b) # Output: "Python"

```

5. **Operator `*` untuk Pengulangan**

```python

kata = "ha"

ulang = kata * 3 # Output: "hahaha"

```

### Catatan Penting:

- **Hanya untuk Tipe Data String**:

Jika menggabungkan *string* dengan non-*string* (misal, `integer`),


gunakan konversi terlebih dahulu:

```python

umur = 25

# Error: hasil = "Umur: " + umur

hasil = "Umur: " + str(umur) # Benar: "Umur: 25"


```

- **Efisiensi**:

Untuk banyak *string*, hindari `+` dalam *loop* karena tidak efisien.
Gunakan `join()` sebagai gantinya.

### Contoh Kasus:

```python

# Concatenation dengan +

nama_depan = "Budi"

nama_belakang = "Santoso"

nama_lengkap = nama_depan + " " + nama_belakang # "Budi Santoso"

# Concatenation dengan join()

kata = ["Concatenation", "di", "Python"]

kalimat = " ".join(kata) # "Concatenation di Python"

# Concatenation dengan f-string

nilai = 95

laporan = f"Nilai: {nilai}/100" # "Nilai: 95/100"

```

Dengan memahami concatenation, Anda dapat fleksibel membangun teks


sesuai kebutuhan program! 🐍

- Iterasi String

**Iterasi String** dalam Python adalah proses mengakses dan memproses


setiap karakter dalam sebuah string satu per satu secara berurutan.
Karena string adalah tipe data *sequence* (urutan) di Python, Anda dapat
melakukan perulangan (*loop*) melalui setiap elemennya (karakter).
### Cara Melakukan Iterasi String:

1. **Menggunakan Loop `for`** (Cara paling umum):

```python

kata = "Python"

for karakter in kata:

print(karakter)

```

Output:

```

```

2. **Menggunakan Indeks** (Loop dengan `range()`):

```python

kata = "Python"

for i in range(len(kata)):

print(kata[i])

```

Output sama seperti di atas.

3. **Menggunakan `enumerate()`** (Jika membutuhkan indeks dan


karakter):

```python
kata = "Py"

for indeks, karakter in enumerate(kata):

print(f"Indeks {indeks}: {karakter}")

```

Output:

```

Indeks 0: P

Indeks 1: y

```

### Contoh Penggunaan Iterasi String:

1. **Menghitung jumlah karakter tertentu**:

```python

teks = "programming"

count = 0

for char in teks:

if char == 'm':

count += 1

print(count) # Output: 2

```

2. **Membalik string**:

```python

original = "Hello"

reversed_str = ""

for char in original:

reversed_str = char + reversed_str

print(reversed_str) # Output: "olleH"

```
3. **Memeriksa palindrom**:

```python

kata = "level"

is_palindrom = True

for i in range(len(kata)//2):

if kata[i] != kata[len(kata)-1-i]:

is_palindrom = False

break

print(is_palindrom) # Output: True

```

4. **Mengubah format string**:

```python

hasil = ""

for char in "PyThOn":

if [Link]():

hasil += [Link]()

else:

hasil += [Link]()

print(hasil) # Output: "pYtHoN"

```

### Karakteristik Penting:

1. **Imutabilitas**:

- String bersifat *immutable* (tidak bisa diubah).

- Iterasi tidak mengubah string asli, tetapi menghasilkan string baru jika
ada modifikasi.
2. **Efisiensi**:

- Iterasi dengan `for char in string` lebih efisien daripada menggunakan


indeks.

- Hindari mengubah string besar dalam loop (lebih baik gunakan `list`
untuk manipulasi kompleks).

3. **Metode Bawaan**:

Banyak metode string yang menggunakan iterasi secara internal,


seperti `count()`, `replace()`, atau `split()`.

### Teknik Lanjutan:

- **List Comprehension**:

```python

huruf_kapital = [char for char in "PyThOn" if [Link]()]

print(huruf_kapital) # Output: ['P', 'T']

```

- **Menggunakan `map()`**:

```python

list_ascii = list(map(ord, "ABC"))

print(list_ascii) # Output: [65, 66, 67]

```

Dengan memahami iterasi string, Anda bisa memproses teks, validasi


input, parsing data, dan banyak operasi teks lainnya secara efisien! 🐍

- Keanggotaan (Membership)

**Strings Membership** dalam Python merujuk pada operasi memeriksa


apakah suatu substring (bagian dari string) terdapat di dalam string
tertentu. Konsep ini menggunakan operator keanggotaan (*membership
operators*) `in` dan `not in` untuk mengevaluasi keberadaan substring.
### Cara Kerja:

1. **Operator `in`**

Mengevaluasi `True` jika substring ditemukan dalam string.

```python

teks = "Belajar Python"

hasil = "Python" in teks

print(hasil) # Output: True

```

2. **Operator `not in`**

Mengevaluasi `True` jika substring **tidak** ditemukan dalam string.

```python

teks = "Belajar Python"

hasil = "Java" not in teks

print(hasil) # Output: True

```

---

### Contoh Penggunaan:

| **Kasus** | **Contoh Kode** | **Hasil** |


**Penjelasan** |

|-------------------------------|------------------------------------------|------------|---------------
------------------------------|

| Pengecekan karakter | `'a' in 'algorithm'` | `True` |


Huruf `a` ada dalam string |

| Pengecekan kata | `'code' in 'programming'` | `False`


| Kata `code` tidak ditemukan |

| Pengecekan sensitif huruf | `'Py' in 'Python'` | `True` |


**Bersifat case-sensitive** (`P` ≠ `p`) |
| Pengecekan spasi | `' ' in 'Hello World'` | `True` |
Spasi dianggap sebagai karakter |

| Pengecekan substring kosong | `'' in 'Python'` | `True`


| Substring kosong selalu dianggap "ada" |

---

### Aplikasi Praktis:

1. **Validasi Input**

```python

email = input("Email: ")

if "@" not in email or "." not in email:

print("Format email salah!")

```

2. **Filtering Data**

```python

buah = ["apel", "mangga", "jeruk", "alpukat"]

hasil = [b for b in buah if "a" in b] # ['apel', 'mangga', 'alpukat']

```

3. **Pengecekan Kata Kunci**

```python

log = "ERROR: File not found"

if "ERROR" in log:

print("Sistem mengalami gangguan!")

```

4. **Pengamanan SQL Injection**

```python
query = input("Query: ")

if ";" in query or "DROP" in [Link]():

print("Query berbahaya ditolak!")

```

---

### Catatan Penting:

1. **Case Sensitivity**

Operasi bersifat *case-sensitive*:

```python

print("python" in "Belajar Python") # False (karena 'p' kecil vs 'P' besar)

```

2. **Substring Kosong**

Substring kosong (`''`) selalu dianggap sebagai bagian dari string apa
pun:

```python

print('' in "Python") # True

```

3. **Efisiensi**

Operasi `in` dioptimalkan di Python (menggunakan algoritma seperti


Boyer-Moore) sehingga efisien bahkan untuk string panjang.

4. **Alternatif Metode**

Bisa juga menggunakan metode string:

```python

teks = "Hello World"

# Menggunakan find()
print([Link]("World") != -1) # True

# Menggunakan count()

print([Link]("lo") > 0) # True

```

Dengan memahami *strings membership*, Anda dapat membuat logika


pengecekan teks yang lebih efisien dan intuitif! 🐍

- Partisi (Partitioning)

**Partitioning String** dalam Python adalah metode untuk membagi


sebuah string menjadi tiga bagian berdasarkan *separator* (pemisah)
yang ditentukan. Hasilnya berupa **tuple 3 elemen**:

`(bagian_sebelum_separator, separator, bagian_setelah_separator)`

---

### Cara Kerja Partitioning:

1. **`[Link](separator)`**

Mencari *separator* **pertama kali muncul** dari kiri (awal string).

2. **`[Link](separator)`**

Mencari *separator* **pertama kali muncul** dari kanan (akhir string).

---

### Contoh Sederhana:

```python

# partition() (pemisah dari kiri)

teks = "Python:Programming:Language"

print([Link](":"))

# Output: ('Python', ':', 'Programming:Language')


# rpartition() (pemisah dari kanan)

print([Link](":"))

# Output: ('Python:Programming', ':', 'Language')

```

---

### Perilaku Ketika Separator Tidak Ditemukan:

- **`partition()`** mengembalikan: `(string_asli, "", "")`

- **`rpartition()`** mengembalikan: `("", "", string_asli)`

Contoh:

```python

teks = "HelloWorld"

print([Link](":")) # Output: ('HelloWorld', '', '')

print([Link](":")) # Output: ('', '', 'HelloWorld')

```

---

### Perbedaan Penting vs `split()`:

| **Fitur** | **Partition** | **Split**


|

|-------------------------|------------------------------------------|----------------------------------
--|

| Jumlah hasil | Selalu 3 bagian (tuple) | Bervariasi (list)


|

| Penyertaan separator | Separator disertakan dalam hasil |


Separator dihilangkan |
| Pemisahan multiple | Hanya memisah di kemunculan
pertama/terakhir | Memisah di semua kemunculan |

Contoh perbandingan:

```python

teks = "a:b:c"

# Partition (hanya pemisah pertama)

print([Link](":")) # Output: ('a', ':', 'b:c')

# Split (semua pemisah)

print([Link](":")) # Output: ['a', 'b', 'c']

```

---

### Aplikasi Praktis:

1. **Ekstraksi nama file dan ekstensi**:

```python

file = "[Link]"

nama, titik, ekstensi = [Link](".")

print(nama) # "document"

print(ekstensi) # "pdf"

```

2. **Memisahkan protokol dan domain URL**:

```python

url = "[Link]

protokol, pemisah, domain = [Link]("://")


print(protokol) # "https"

print(domain) # "[Link]"

```

3. **Handling input dengan format tetap**:

```python

data = "nama=Andi;umur=25"

bagian, separator, sisanya = [Link](";")

print(bagian) # "nama=Andi"

```

---

### Catatan Penting:

1. **Separator harus berupa string**:

```python

"abc".partition(123) # Error! Separator harus string.

```

2. **Case-sensitive**:

```python

print("PYTHON".partition("p")) # ('PYTHON', '', '')

```

3. **Separator kosong (`""`)** tidak valid:

```python

"hello".partition("") # ValueError: empty separator

```
4. **Efisiensi**:

Partition sangat efisien karena hanya mencari satu kemunculan


separator.

---

### Teknik Lanjutan:

**Kombinasi dengan `unpacking`**:

```python

teks = "key:value"

kunci, _, nilai = [Link](":") # _ mengabaikan separator

print(kunci) # "key"

print(nilai) # "value"

```

Dengan memahami partitioning, Anda dapat mengekstrak bagian string


secara presisi tanpa kehilangan informasi separator! 🐍

- Fungsi Bawaan

**Fungsi Bawaan String (Built-in String Functions/Methods)** dalam


Python adalah kumpulan operasi yang sudah terintegrasi langsung
dengan tipe data `str`. Fungsi-fungsi ini memungkinkan manipulasi,
pemeriksaan, dan transformasi string tanpa perlu menulis kode dari awal.

### Ciri Khas Fungsi Bawaan String:

1. **Dipakai sebagai metode**: Dipanggil dengan sintaks


`string.nama_fungsi()`.

2. **Tidak mengubah string asli**: Karena string bersifat *immutable*,


fungsi selalu mengembalikan string baru.

3. **Sangat banyak dan variatif**: Python menyediakan ≈50 metode


bawaan untuk string.
---

### Kategori Utama Fungsi Bawaan String:

#### 1. **Transformasi Kasus Huruf**

| Fungsi | Contoh | Hasil |

|-----------------|---------------------------------|---------------------|

| `upper()` | `"PyThon".upper()` | `"PYTHON"` |

| `lower()` | `"PyThon".lower()` | `"python"` |

| `capitalize()` | `"hello".capitalize()` | `"Hello"` |

| `title()` | `"python basics".title()` | `"Python Basics"` |

| `swapcase()` | `"PyThOn".swapcase()` | `"pYtHoN"` |

| `casefold()` | `"ß".casefold()` | `"ss"` (case-insensitive) |

#### 2. **Pencarian & Pemeriksaan**

| Fungsi | Contoh | Hasil |

|-----------------|---------------------------------|----------|

| `find()` | `"apple".find("p")` | `1` |

| `index()` | `"apple".index("pl")` | `2` |

| `count()` | `"banana".count("a")` | `3` |

| `startswith()` | `"hello".startswith("he")` | `True` |

| `endswith()` | `"world".endswith("ld")` | `True` |

| `isalnum()` | `"abc123".isalnum()` | `True` |

| `isalpha()` | `"Python".isalpha()` | `True` |

| `isdigit()` | `"123".isdigit()` | `True` |

#### 3. **Pemotongan & Pemisahan**

| Fungsi | Contoh | Hasil |

|-----------------|---------------------------------|-------------------------|
| `split()` | `"a,b,c".split(",")` | `['a', 'b', 'c']` |

| `rsplit()` | `"a.b.c".rsplit(".", 1)` | `['a.b', 'c']` |

| `partition()` | `"py:thon".partition(":")` | `('py', ':', 'thon')` |

| `splitlines()` | `"line1\nline2".splitlines()` | `['line1', 'line2']` |

| `strip()` | `" text ".strip()` | `"text"` |

| `lstrip()` | `"##data".lstrip("#")` | `"data"` |

#### 4. **Penggabungan & Formatting**

| Fungsi | Contoh | Hasil |

|-----------------|-----------------------------------------|-------------------|

| `join()` | `",".join(['a','b','c'])` | `"a,b,c"` |

| `format()` | `"{} {}".format("Hello", "World")` | `"Hello World"`


|

| `zfill()` | `"42".zfill(5)` | `"00042"` |

| `center()` | `"hi".center(10, "-")` | `"----hi----"` |

#### 5. **Penggantian & Encoding**

| Fungsi | Contoh | Hasil |

|-----------------|---------------------------------|---------------------|

| `replace()` | `"tea".replace("t", "c")` | `"cea"` |

| `translate()` | ```"abc".translate({97: "X"})```| `"Xbc"` (a→X) |

| `encode()` | `"é".encode("utf-8")` | `b'\xc3\xa9'` |

| `maketrans()` | ```[Link]("ab", "xy")``` | Tabel translasi |

---

### Contoh Praktis Penggunaan:

```python

# Validasi password
password = "P@ssw0rd"

is_valid = (

len(password) >= 8

and any([Link]() for c in password)

and any([Link]() for c in password)

and any(not [Link]() for c in password)

# Membersihkan input pengguna

user_input = " user@[Link] "

clean_input = user_input.strip().lower() # "user@[Link]"

# Parsing data CSV

data = "John,Doe,30"

first, last, age = [Link](",") # first="John", last="Doe", age="30"

# Format laporan

report = "Nama: {}, Usia: {}".format("Budi", 25) # "Nama: Budi, Usia:


25"

```

---

### Keunggulan Fungsi Bawaan:

1. **Optimisasi**: Diimplementasikan dalam C (cepat dan efisien).

2. **Ribuan jam pengujian**: Sangat stabil dan bebas bug.

3. **Konsistensi**: Perilaku seragam di semua platform.


> 💡 **Tip**: Gunakan `dir(str)` untuk melihat daftar lengkap metode
string, atau baca [dokumentasi
resmi]([Link]

Fungsi bawaan string adalah "pisau Swiss Army" untuk manipulasi teks di
Python—menguasainya akan membuat pengolahan string jadi jauh lebih
efisien! 🐍

- Karakter Escape

**Karakter Escape String** dalam Python adalah karakter khusus yang


diawali dengan tanda **backslash (`\`)** yang digunakan untuk
merepresentasikan karakter yang tidak dapat ditulis secara langsung
dalam string atau memiliki makna khusus. Karakter escape
memungkinkan Anda menyisipkan simbol tertentu, mengontrol format
teks, atau menghindari konflik sintaksis.

---

### **Daftar Karakter Escape Umum**

Berikut karakter escape paling umum beserta fungsinya:

| **Escape Sequence** | **Deskripsi**


| **Contoh** | **Output** |

|---------------------|-------------------------------------------------------------------------------|-
-------------------------------|------------------------|

| `\\` | Menyisipkan backslash (`\`)


| `"C:\\folder"` | `C:\folder` |

| `\'` | Menyisipkan single quote (`'`)


| `'It\'s Python'` | `It's Python` |

| `\"` | Menyisipkan double quote (`"`)


| `"Dia bilang: \"Halo!\""` | `Dia bilang: "Halo!"` |

| `\n` | Baris baru (*newline*) |


`"Baris 1\nBaris 2"` | `Baris 1`<br>`Baris 2`|
| `\t` | Tab horizontal |
`"Nama:\tAlice"` | `Nama: Alice` |

| `\r` | Mengembalikan kursor ke awal baris (*carriage return*)


| `"Hello\rWorld"` | `World` (timpa teks) |

| `\b` | Backspace (menghapus 1 karakter sebelumnya)


| `"Hel\blo"` | `Hello` |

| `\f` | Form feed (ganti halaman - jarang digunakan)


| `"Halaman 1\fHalaman 2"` | Tergantung terminal |

| `\ooo` | Karakter berdasarkan **kode oktal** (misal: `\101` =


`A`) | `"\101"` | `A` |

| `\xhh` | Karakter berdasarkan **kode heksadesimal** (misal: `\


x41` = `A`) | `"\x41"` | `A` |

| `\uXXXX` | Karakter Unicode 16-bit (misal: `\u00A9` = ©)


| `"Hak cipta \u00A9"` | `Hak cipta ©` |

| `\UXXXXXXXX` | Karakter Unicode 32-bit (misal: `\U0001F600` = 😀)


| `"Senang \U0001F600"` | `Senang 😀` |

---

### **Contoh Penggunaan**

#### 1. **Menghindari Konflik Sintaks**

```python

# Single quote dalam string single quote

print('Don\'t stop!') # Output: Don't stop!

# Double quote dalam string double quote

print("Dia berkata: \"Halo!\"") # Output: Dia berkata: "Halo!"

```

#### 2. **Format Teks**

```python

# Baris baru dan tab


print("Header:\n\t- Item 1\n\t- Item 2")

# Output:

# Header:

# - Item 1

# - Item 2

```

#### 3. **Unicode dan Emoji**

```python

print("Euro: \u20AC, Emoji: \U0001F604") # Output: Euro: €, Emoji: 😄

```

---

### **Raw String: Menonaktifkan Karakter Escape**

Tambahkan **`r`** sebelum string untuk mengabaikan karakter escape:

```python

# Tanpa raw string

print("C:\new\folder")

# Output:

# C:

# ew

# older

# Dengan raw string

print(r"C:\new\folder") # Output: C:\new\folder

```

---
### **Kasus Khusus**

1. **Backslash di Akhir String**

Tambahkan extra backslash (`\\`):

```python

print("String ends with backslash: \\") # Output: String ends with


backslash: \

```

2. **String Multi-baris**

Gunakan **triple quotes** (`'''`/`"""`) untuk string yang mengandung


banyak karakter escape:

```python

multi_line = """

Line 1: \tTabbed

Line 2: Special char: \"

"""

```

---

### **Mengapa Karakter Escape Penting?**

1. **Kemampuan Reprentasi**: Menampilkan karakter yang tidak tersedia


di keyboard (seperti `©`, `€`).

2. **Kontrol Format**: Mengatur tata letak teks (baris baru, tab).

3. **Penanganan Path**: Menulis path file di Windows tanpa konflik (`C:\\


folder`).

4. **Keamanan**: Menghindari injeksi kode dengan karakter khusus.

Dengan memahami karakter escape, Anda bisa menulis string yang lebih
fleksibel dan menghindari error sintaksis! 🐍
- **List**

- Pembuatan List

### Apa itu Pembuatan List dalam Python?

**List** (daftar) adalah struktur data bawaan Python yang digunakan


untuk menyimpan kumpulan data **terurut**, **mutable** (dapat
diubah), dan **heterogen** (bisa berisi tipe data berbeda). List dibuat
menggunakan **tanda kurung siku `[]`**, dengan elemen dipisahkan
koma.

---

### Cara Membuat List

#### 1. **List Kosong**

```python

list_kosong = []

list_kosong_alternatif = list() # Menggunakan konstruktor list()

```

#### 2. **List dengan Elemen**

```python

angka = [1, 2, 3, 4, 5] # List integer

buah = ["apel", "mangga", "jeruk"] # List string

campuran = [10, "hello", 3.14, True] # List campuran tipe data

```

#### 3. **List Bersarang (Nested List)**

```python

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # List 2D (matriks)

```
#### 4. **Menggunakan `list()`**

Konversi tipe data lain menjadi list:

```python

list_dari_string = list("Python") # Output: ['P', 'y', 't', 'h', 'o', 'n']

list_dari_range = list(range(5)) # Output: [0, 1, 2, 3, 4]

list_dari_tuple = list((1, 2, 3)) # Output: [1, 2, 3]

```

#### 5. **List Comprehension**

Membuat list secara dinamis dengan sintaks ringkas:

```python

kuadrat = [x**2 for x in range(5)] # Output: [0, 1, 4, 9, 16]

genap = [x for x in range(10) if x % 2 == 0] # Output: [0, 2, 4, 6, 8]

```

---

### Fitur Penting List

1. **Mutable**

Elemen list bisa diubah setelah pembuatan:

```python

buah = ["apel", "mangga", "jeruk"]

buah[1] = "durian" # Mengubah elemen indeks 1

print(buah) # Output: ["apel", "durian", "jeruk"]

```

2. **Heterogen**

Bisa menampung berbagai tipe data:


```python

data = [42, "Python", 3.14, [1, 2, 3]]

```

3. **Operasi Dasar**

- **Gabung list**: `+`

```python

list1 = [1, 2]; list2 = [3, 4]

gabung = list1 + list2 # Output: [1, 2, 3, 4]

```

- **Pengulangan**: `*`

```python

ulang = ["halo"] * 3 # Output: ["halo", "halo", "halo"]

```

- **Cek keanggotaan**: `in`

```python

print("apel" in buah) # Output: True

```

---

### Contoh Praktis

```python

# Membuat list angka genap 0-10

genap = [x for x in range(11) if x % 2 == 0]

print(genap) # Output: [0, 2, 4, 6, 8, 10]

# Membuat list dari input user

input_user = input("Masukkan angka (pisah koma): ")


list_angka = [int(angka) for angka in input_user.split(",")]

print(list_angka) # Contoh input "1,2,3" → [1, 2, 3]

```

---

### Kesimpulan

Pembuatan list di Python sangat fleksibel dan mendukung:

- Inisialisasi manual: `[1, 2, 3]`

- Konversi objek lain: `list(range(5))`

- Dinamis dengan **list comprehension**: `[ekspresi for item in iterable]`.

List adalah fondasi penting untuk manipulasi data, pengulangan, dan


penyimpanan koleksi objek dalam Python. 🐍

- Pengindeksan (Maju/Mundur)

### Pengindeksan List Maju dan Mundur dalam Python

Pengindeksan (indexing) pada list Python memungkinkan Anda


mengakses elemen berdasarkan posisinya. Terdapat dua cara
pengindeksan:

#### 1. **Pengindeksan Maju (Positive Indexing)**

- Dimulai dari **indeks 0** untuk elemen pertama

- Bertambah secara berurutan ke kanan

- Format: `list[indeks]`

```python

buah = ['apel', 'mangga', 'jeruk', 'durian', 'anggur']

# Indeks: 0 1 2 3 4
print(buah[0]) # Output: 'apel'

print(buah[2]) # Output: 'jeruk'

print(buah[4]) # Output: 'anggur'

```

#### 2. **Pengindeksan Mundur (Negative Indexing)**

- Dimulai dari **indeks -1** untuk elemen terakhir

- Berkurang secara berurutan ke kiri

- Format: `list[indeks_negatif]`

```python

buah = ['apel', 'mangga', 'jeruk', 'durian', 'anggur']

# Indeks: -5 -4 -3 -2 -1

print(buah[-1]) # Output: 'anggur'

print(buah[-3]) # Output: 'jeruk'

print(buah[-5]) # Output: 'apel'

```

### Perbandingan Visual

```

Indeks Maju: [ 0 , 1 , 2 , 3 , 4 ]

+---------------------------------------+

List: | apel | mangga | jeruk | durian| anggur|

+---------------------------------------+

Indeks Mundur: [ -5 , -4 , -3 , -2 , -1 ]

```
### Aplikasi dalam Slicing

Kedua jenis indeks dapat digunakan untuk slicing:

```python

print(buah[1:4]) # Maju: ['mangga', 'jeruk', 'durian']

print(buah[-4:-1]) # Mundur: ['mangga', 'jeruk', 'durian']

print(buah[2:-1]) # Campuran: ['jeruk', 'durian']

```

### Keuntungan Pengindeksan Mundur

1. **Akses elemen akhir tanpa tahu panjang list**

```python

# Tanpa negative indexing

last_element = buah[len(buah) - 1] # ribet

# Dengan negative indexing

last_element = buah[-1] # simpel

```

2. **Memotong dari akhir list**

```python

# 2 elemen terakhir

print(buah[-2:]) # Output: ['durian', 'anggur']

```

3. **Reversing elemen**

```python

print(buah[::-1]) # Output: ['anggur', 'durian', 'jeruk', 'mangga', 'apel']

```
### Contoh Operasi Gabungan

```python

# Mengganti elemen ke-3 dari akhir

buah[-3] = "NANAS"

print(buah) # Output: ['apel', 'mangga', 'NANAS', 'durian', 'anggur']

# Memotong dari indeks 1 sampai 3 dari akhir

print(buah[1:-2]) # Output: ['mangga']

```

### Kesimpulan

- **Indeks Maju**: `[0]` = elemen pertama, `[1]` = elemen kedua, dst

- **Indeks Mundur**: `[-1]` = elemen terakhir, `[-2]` = elemen kedua


terakhir, dst

Keduanya memberikan fleksibilitas tinggi dalam manipulasi list tanpa


perlu selalu menghitung panjang list.

- Pemotongan (Slicing)

### **List Slicing dalam Python**

**List slicing** adalah teknik untuk mengambil sebagian elemen dari


sebuah list dengan menentukan rentang indeks (`start:stop:step`).
Hasilnya adalah **list baru** yang berisi elemen-elemen terpilih.

#### **Format Dasar Slicing**

```python

list_baru = list_awal[start:stop:step]

```

- **`start`**: Indeks awal (inklusif). Default: `0`.

- **`stop`**: Indeks akhir (eksklusif). Default: `panjang list`.


- **`step`**: Langkah/lompatan antar elemen. Default: `1`.

---

### **Contoh Slicing dengan Indeks Positif**

```python

angka = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Ambil elemen indeks 2 hingga 5 (eksklusif)

print(angka[2:5]) # Output: [2, 3, 4]

# Dari awal hingga indeks 4

print(angka[:4]) # Output: [0, 1, 2, 3]

# Dari indeks 6 hingga akhir

print(angka[6:]) # Output: [6, 7, 8, 9]

# Setiap elemen ke-2

print(angka[::2]) # Output: [0, 2, 4, 6, 8]

```

---

### **Contoh Slicing dengan Indeks Negatif**

```python

angka = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 3 elemen terakhir

print(angka[-3:]) # Output: [7, 8, 9]


# Dari indeks -7 hingga -3 (eksklusif)

print(angka[-7:-3]) # Output: [3, 4, 5]

# Balik urutan list

print(angka[::-1]) # Output: [9, 8, 7, ..., 0]

# Setiap elemen ke-2 dari belakang

print(angka[::-2]) # Output: [9, 7, 5, 3, 1]

```

---

### **Kombinasi Indeks Positif & Negatif**

```python

angka = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Dari indeks 2 hingga 6 dari belakang

print(angka[2:-2]) # Output: [2, 3, 4, 5, 6, 7]

# Balik sebagian: indeks 5 hingga 1 (mundur)

print(angka[5:1:-1]) # Output: [5, 4, 3, 2]

```

---

### **Step yang Lebih Kompleks**

```python

angka = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Lompati 3 elemen (setiap ke-4 elemen)

print(angka[::4]) # Output: [0, 4, 8]

# Dari indeks 9 hingga 3 (mundur, lompat 2)

print(angka[9:3:-2]) # Output: [9, 7, 5]

```

---

### **Modifikasi List dengan Slicing**

Anda bisa mengubah sublist menggunakan slicing:

```python

angka = [0, 1, 2, 3, 4, 5]

# Ganti elemen indeks 1-3

angka[1:4] = [10, 20, 30]

print(angka) # Output: [0, 10, 20, 30, 4, 5]

# Hapus elemen indeks 2-4

angka[2:5] = []

print(angka) # Output: [0, 10, 5]

```

---

### **Aturan Penting**

1. Jika `start` > `stop` dan `step` positif → mengembalikan **list


kosong**.
```python

print(angka[5:2]) # Output: []

```

2. Jika indeks di luar batas, Python akan otomatis menyesuaikan ke batas


terdekat.

```python

print(angka[:100]) # Output: seluruh list

```

3. Slicing selalu menghasilkan **list baru** (shallow copy untuk elemen).

---

### **Diagram Visual Slicing**

```

Indeks: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

List: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

│ │ │ │ │ │ │ │ │ │

├──┼──┼──┼──┼──┼──┼──┼──┼──┤

Contoh: [1:7:2] → [1, 3, 5]

start=1, stop=7, step=2

```

---

### **Aplikasi Praktis**

1. **Membalik string**:

```python

teks = "Python"

print(teks[::-1]) # Output: "nohtyP"


```

2. **Ekstrak bagian tertentu**:

```python

data = ["A", "B", "C", "D", "E", "F"]

tengah = data[2:4] # Output: ["C", "D"]

```

3. **Hapus setiap elemen ke-n**:

```python

angka = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

angka_mod = angka[::2] # Output: [0, 2, 4, 6, 8]

```

List slicing adalah alat **efisien** untuk manipulasi data tanpa perulangan
eksplisit. 🚀

- Menambah/Hapus/Ubah Item

### **Manipulasi Item List di Python: Tambah, Hapus, Ubah**

List Python bersifat **mutable**, artinya Anda dapat memodifikasi isinya


setelah pembuatan. Berikut penjelasan lengkap operasi dasar:

---

#### **1. Menambah Item**

Ada beberapa cara menambahkan elemen baru:

| Metode | Contoh Kode | Deskripsi


| Output List Baru |
|---------------------|------------------------------|--------------------------------------------|-----
---------------------|

| **`append()`** | `[Link]("naga")` | Tambah item di


**akhir** list | `[..., "naga"]` |

| **`insert()`** | `[Link](1, "kiwi")` | Sisipkan item di **posisi


spesifik** | `[..., "kiwi", ...]` |

| **`extend()`** | `[Link](["melon", "pepaya"])` | Gabungkan list


lain di **akhir** | `[..., "melon", "pepaya"]` |

| **`+` operator** | `buah + ["anggur"]` | Buat list baru hasil


penggabungan | List baru (tidak modifkasi asli) |

| **`*` operator** | `[0] * 3` | Duplikasi item: `[0, 0, 0]`


| List baru |

**Contoh:**

```python

numbers = [1, 2, 3]

[Link](4) # [1, 2, 3, 4]

[Link](0, 0) # [0, 1, 2, 3, 4]

[Link]([5, 6]) # [0, 1, 2, 3, 4, 5, 6]

```

---

#### **2. Menghapus Item**

Metode penghapusan berdasarkan kondisi:

| Metode | Contoh Kode | Deskripsi


|

|---------------------|------------------------------|--------------------------------------------|

| **`remove()`** | `[Link]("apel")` | Hapus **item spesifik**


(error jika tidak ada) |
| **`pop()`** | `[Link](1)` | Hapus item di **indeks** &
kembalikan nilainya |

| **`pop()` kosong** | `[Link]()` | Hapus **item terakhir**


|

| **`del` statement** | `del buah[0]` | Hapus berdasarkan


indeks/slice |

| **`clear()`** | `[Link]()` | Kosongkan seluruh list


|

| **Slicing kosong** | `buah[1:3] = []` | Hapus sublist dengan


slicing |

**Contoh:**

```python

data = ["a", "b", "c", "d", "e"]

[Link]("c") # ['a', 'b', 'd', 'e']

[Link](0) # Hapus 'a', return 'a' → data: ['b', 'd', 'e']

del data[1] # ['b', 'e']

data[0:2] = [] # []

```

---

#### **3. Mengubah Item**

Modifikasi elemen eksisting:

| Metode | Contoh Kode | Deskripsi


|

|----------------------------|----------------------------------|------------------------------------|

| **Indeks langsung** | `buah[0] = "Alpukat"` | Ganti item di


indeks spesifik |

| **Slicing assignment** | `buah[1:3] = ["X", "Y"]` | Ganti sublist


dengan list baru |
| **Slicing + step** | `angka[::2] = [0, 0, 0]` | Ganti item dengan
pola tertentu |

**Contoh:**

```python

colors = ["red", "green", "blue"]

colors[1] = "yellow" # ['red', 'yellow', 'blue']

colors[0:2] = ["black"] # Ganti 2 elemen dengan 1 item: ['black', 'blue']

# Ganti elemen ganjil

nums = [1, 2, 3, 4, 5]

nums[::2] = [10, 20, 30] # [10, 2, 20, 4, 30]

```

---

### **Operasi Gabungan & Catatan Penting**

1. **Modifikasi saat iterasi**:

Hindari mengubah panjang list saat iterasi! Gunakan teknik khusus:

```python

# Hapus bilangan genap dengan list comprehension (buat list baru)

nums = [1, 2, 3, 4, 5]

nums_baru = [x for x in nums if x % 2 != 0] # [1, 3, 5]

```

2. **Perbandingan `del` vs `pop()`**:

```python

arr = [10, 20, 30]

nilai_pop = [Link](1) # nilai_pop = 20, arr = [10, 30]


del arr[1] # arr = [10] (tidak return nilai)

```

3. **Efisiensi**:

- `append()`/`pop()`: O(1) → efisien

- `insert(0)`/`remove()`: O(n) → kurang efisien untuk list besar

---

### **Diagram Visual: Operasi Dasar**

```

List Awal: ["🍎", "🍌", "🍊"]

1. Append: ["🍎", "🍌", "🍊", "🍇"]

2. Insert(1): ["🍎", "🥝", "🍌", "🍊", "🍇"]

3. Remove: ["🍎", "🥝", "🍊", "🍇"] (hapus "🍌")

4. Ubah [0]: ["🍍", "🥝", "🍊", "🍇"]

```

Dengan menguasai operasi ini, Anda dapat memanipulasi list Python


secara efektif untuk berbagai kebutuhan pemrograman! 🐍💻

- Salin List (Copy)

### **Penyalinan (Copying) List dalam Python**

Penyalinan list adalah proses membuat **duplikat independen** dari list


asli, sehingga modifikasi pada salinan tidak memengaruhi list asli (dan
sebaliknya). Ini penting karena **assignment biasa (`=`) tidak membuat
salinan sebenarnya**, melainkan hanya referensi ke objek yang sama.

---
#### **1. Jenis-Jenis Penyalinan List**

| Jenis Salinan | Metode | Perubahan pada Salinan vs Asli


| Cocok Untuk |

|---------------------|-------------------------|---------------------------------------------------|---
-----------------------|

| **Shallow Copy** | `copy()`, `list()`, `[:]` | Tidak memengaruhi asli


(kecuali untuk elemen mutable bersarang) | List 1D/tanpa nested list |

| **Deep Copy** | `[Link]()` | Sepenuhnya independen


| List bersarang (nested) |

| **Assignment (`=`)**| `list_baru = list_asli` | Selalu memengaruhi asli


(karena referensi sama) | Tidak direkomendasikan |

---

#### **2. Shallow Copy (Salinan Dangkal)**

Membuat list baru, tetapi **elemen mutable di dalamnya (seperti nested


list) masih berbagi referensi** dengan list asli.

**Contoh Metode:**

```python

asli = [1, [2, 3], 4]

# Metode 1: copy()

salin1 = [Link]()

# Metode 2: slicing [:]

salin2 = asli[:]

# Metode 3: list()

salin3 = list(asli)
```

**Perilaku:**

```python

salin1[0] = 99 # Tidak memengaruhi asli

print(asli) # Output: [1, [2, 3], 4]

salin1[1][0] = 88 # Memengaruhi asli karena nested list!

print(asli) # Output: [1, [88, 3], 4]

```

---

#### **3. Deep Copy (Salinan Mendalam)**

Membuat duplikat **sepenuhnya independen**, termasuk semua elemen


di dalamnya (termasuk nested list).

**Gunakan modul `copy`:**

```python

import copy

asli = [1, [2, 3], 4]

salin_deep = [Link](asli)

salin_deep[1][0] = 88

print(asli) # Output: [1, [2, 3], 4] (tidak berubah)

print(salin_deep) # Output: [1, [88, 3], 4]

```

---
#### **4. Assignment Biasa (Bukan Salinan!)**

Hanya membuat **referensi baru ke objek yang sama**:

```python

asli = [1, 2, 3]

referensi = asli # Bukan salinan!

referensi[0] = 99

print(asli) # Output: [99, 2, 3] (asli ikut berubah)

```

---

#### **5. Visualisasi Perbedaan**

```

Assignment (`=`):

asli → [🍎, 🍌]

referensi ───┘

Shallow Copy:

asli → [🍎, [🍊]]

salin → [🍎, [🍊]] # Elemen nested masih shared!

Deep Copy:

asli → [🍎, [🍊]]

salin_deep → [🍎, [🍊]] # Sepenuhnya terpisah

```

---
#### **6. Kapan Menggunakan Shallow vs Deep Copy?**

| Scenario | Rekomendasi |

|-----------------------------------|-----------------|

| List 1D (tanpa nested list) | Shallow Copy |

| List berisi tipe data immutable | Shallow Copy |

| List bersarang (nested list/dict) | Deep Copy |

| Tidak yakin | Deep Copy |

---

#### **7. Contoh Praktis**

```python

# Shallow Copy untuk list sederhana

numbers = [10, 20, 30]

numbers_copy = [Link]()

numbers_copy.append(40)

print(numbers) # [10, 20, 30] (tidak berubah)

# Deep Copy untuk nested list

import copy

matrix = [[1, 2], [3, 4]]

matrix_copy = [Link](matrix)

matrix_copy[0][0] = 99

print(matrix) # [[1, 2], [3, 4]] (asli aman)

```

---
### **Peringatan Penting**

- **Shallow Copy** cukup untuk list 1D, tetapi **berbahaya untuk nested
list**.

- **Deep Copy** lebih aman tetapi lebih lambat dan membutuhkan lebih
banyak memori.

- Selalu gunakan **`copy` atau `deepcopy`** jika ingin duplikat


independen, hindari assignment (`=`).

Dengan memahami teknik penyalinan, Anda terhindar dari bug manipulasi


data tak terduga! 🐍🔁

- Gabungan List (Join)

### **Penggabungan (Join) List dalam Python**

Penggabungan list (list joining) adalah proses menggabungkan dua atau


lebih list menjadi satu list baru. Python menyediakan beberapa cara untuk
melakukan ini:

---

#### **1. Operator `+` (Concatenation)**

Menggabungkan list secara langsung dan menghasilkan list baru:

```python

list1 = [1, 2, 3]

list2 = ['a', 'b', 'c']

gabung = list1 + list2

print(gabung) # Output: [1, 2, 3, 'a', 'b', 'c']

```

#### **2. Metode `extend()`**

Menambahkan elemen list lain ke akhir list *existing* (modifikasi list asli):
```python

list1 = [1, 2, 3]

list2 = ['a', 'b', 'c']

[Link](list2)

print(list1) # Output: [1, 2, 3, 'a', 'b', 'c'] (list1 termodifikasi)

```

#### **3. Unpacking Operator `*` (Python 3.5+)**

Berguna untuk menggabungkan banyak list sekaligus:

```python

list1 = [1, 2]

list2 = ['a', 'b']

list3 = [True, False]

gabung = [*list1, *list2, *list3]

print(gabung) # Output: [1, 2, 'a', 'b', True, False]

```

#### **4. Fungsi `[Link]()`**

Efisien untuk menggabungkan list besar (mengembalikan iterator):

```python

from itertools import chain

list1 = [1, 2, 3]

list2 = ['x', 'y']

gabung = list(chain(list1, list2))

print(gabung) # Output: [1, 2, 3, 'x', 'y']

```

---
### **Join List vs. Join String**

Jangan tertukar dengan metode string `join()`!

Metode `join()` digunakan untuk **menggabungkan list of strings**


menjadi satu string:

```python

kata = ['Python', 'itu', 'kuat']

kalimat = " ".join(kata)

print(kalimat) # Output: "Python itu kuat"

# Dengan separator kustom:

path = "/".join(['folder', 'sub', '[Link]'])

print(path) # Output: "folder/sub/[Link]"

```

---

### **Perbandingan Metode Penggabungan List**

| Metode | Kelebihan | Kekurangan |

|-----------------|------------------------------------------|--------------------------------|

| **`+`** | Simpel, intuitif | Membuat list baru (kurang


efisien untuk list besar) |

| **`extend()`** | Efisien (modifikasi di tempat) | Mengubah list asli


|

| **`*` unpacking** | Fleksibel untuk banyak list | Hanya tersedia di


Python 3.5+ |

| **`chain()`** | Paling efisien untuk list sangat besar | Perlu import


modul |

---
### **Contoh Aplikasi Praktis**

#### Gabungkan list dengan filter:

```python

angka = [1, 2, 3]

huruf = ['a', 'b', 'c']

gabung_filter = [*angka, *filter(lambda x: x != 'b', huruf)]

print(gabung_filter) # Output: [1, 2, 3, 'a', 'c']

```

#### Gabungkan nested list:

```python

list_matrix = [[1, 2], [3, 4], [5, 6]]

gabung_flat = []

for sublist in list_matrix:

gabung_flat.extend(sublist)

print(gabung_flat) # Output: [1, 2, 3, 4, 5, 6]

# Cara modern (list comprehension + unpacking):

gabung_flat = [item for sublist in list_matrix for item in sublist]

```

---

### **Peringatan Penting**

1. **Efek Samping `extend()`**:

```python

list1 = [1, 2]

list2 = list1

[Link]([3, 4])
print(list2) # Output: [1, 2, 3, 4] (list2 ikut berubah!)

```

2. **Perbedaan Tipe Data**:

```python

# [1, 2] + ['a', 'b'] → Berhasil

# [1, 2] + 'ab' → Error! (string bukan list)

```

3. **Alternatif untuk List of Strings**:

```python

# Gunakan join() untuk efisiensi:

''.join(['a','b']) # Output: "ab" (lebih cepat dari loop)

```

---

### **Kesimpulan**

- Gunakan **`+`** untuk penggabungan sederhana dan cepat.

- Gunakan **`extend()`** untuk modifikasi list *in-place*.

- Pilih **`[Link]()`** untuk operasi pada dataset besar.

- Metode **string `join()`** khusus untuk list of strings → konversi ke


string.

Dengan teknik ini, Anda bisa menggabungkan list sesuai kebutuhan


performa dan fungsionalitas! 🐍🚀

- Keanggotaan (Membership)

### **List Membership dalam Python**


**List membership** adalah mekanisme untuk memeriksa apakah suatu
elemen **ada atau tidak** dalam sebuah list. Python menyediakan
operator khusus dan fungsi bawaan untuk melakukan pengecekan
keanggotaan (membership test) ini.

---

#### **1. Operator Membership Dasar**

| Operator | Contoh | Arti |

|----------|-------------------------|----------------------------------|

| **`in`** | `'apel' in buah` | True jika elemen **ada** |

| **`not in`** | `'naga' not in buah` | True jika elemen **tidak ada** |

**Contoh:**

```python

buah = ["apel", "mangga", "jeruk"]

print("apel" in buah) # Output: True

print("anggur" in buah) # Output: False

print("naga" not in buah) # Output: True

```

---

#### **2. Pengecekan dengan Tipe Data Berbeda**

Membership test **bersifat case-sensitive** dan memperhatikan tipe data:

```python

data = [10, "10", 3.14, [1, 2]]

print(10 in data) # True (integer 10)


print("10" in data) # True (string "10")

print(3.14 in data) # True

print([1, 2] in data) # True

print("3.14" in data) # False (string vs float)

```

---

#### **3. Implementasi di Balik Layar**

Python melakukan **pencarian linear (linear search)** untuk membership


test:

```python

# Proses setara:

def cek_keanggotaan(elemen, list):

for item in list:

if item == elemen: # Perbandingan dengan `==`

return True

return False

```

- Kompleksitas waktu: **O(n)** (semakin besar list, semakin lambat)

- Untuk optimasi, pertimbangkan menggunakan **set** jika tidak butuh


urutan.

---

#### **4. Perbandingan dengan Tipe Data Lain**

| Tipe Data | Membership Test | Efisiensi | Catatan |

|------------------|-----------------|-----------|-----------------------|

| **List** | `in`, `not in` | O(n) | Pencarian linear |

| **Set** | `in`, `not in` | O(1) | Hash-based lookup |


| **String** | `in`, `not in` | O(n) | Cek substring |

| **Dictionary** | `in`, `not in` | O(1) | Cek kunci (keys) |

---

#### **5. Aplikasi Praktis**

1. **Validasi input:**

```python

pilihan_valid = ["yes", "no", "y", "n"]

user_input = input("Lanjut? (yes/no): ").lower()

if user_input not in pilihan_valid:

print("Input tidak valid!")

```

2. **Filter data:**

```python

angka = [1, 5, 8, 3, 10, 7]

target = [5, 10, 15]

# Ambil angka yang ada di target

hasil = [x for x in angka if x in target] # [5, 10]

```

3. **Cek kekosongan list (indirect):**

```python

if not list_kosong: # Cek panjang list == 0

print("List kosong")

```
---

#### **6. Peringatan Penting**

- **Case Sensitivity:**

```python

print("Apple" in ["apple", "banana"]) # False (huruf kapital)

```

- **Perbandingan Objek:**

```python

class Warna:

def __init__(self, nama):

[Link] = nama

merah1 = Warna("merah")

merah2 = Warna("merah")

print(merah1 in [merah2]) # False (objek berbeda meski properti sama)

```

- **False Positif pada Nested List:**

```python

print([1, 2] in [1, 2, 3]) # False (cari list, bukan elemen)

print([1, 2] in [[1, 2], [3, 4]]) # True

```

---

### **Optimasi untuk List Besar**

Untuk list dengan >1000 elemen, gunakan **set** untuk membership test
O(1):
```python

list_besar = [i for i in range(1000000)]

set_besar = set(list_besar)

# Lebih cepat 1000x+!

print(999999 in set_besar) # O(1) vs O(n) pada list

```

---

### **Kesimpulan**

List membership (`in` dan `not in`) digunakan untuk:

1. Memeriksa keberadaan elemen dalam list

2. Validasi data

3. Filtering elemen

4. Pengendalian alur program

Kelemahan utama: **tidak efisien untuk list sangat besar**. Untuk


skenario performa kritis, konversi ke **set** atau gunakan struktur data
lain yang lebih optimal! 🚀

- Membalik & Mengurutkan

### **Membalik dan Mengurutkan List dalam Python**

Operasi membalik (reverse) dan mengurutkan (sort) adalah manipulasi


dasar untuk mengubah urutan elemen dalam list Python. Berikut
penjelasan lengkapnya:

---
#### **1. Membalik Urutan List (Reversing)**

Membalik list berarti mengubah urutan elemen sehingga elemen pertama


menjadi terakhir dan sebaliknya.

**Metode Membalik List:**

| Metode | Contoh | Perubahan List Asli | Hasil


Return |

|-----------------------------|---------------------------------|---------------------|-----------------
--|

| **Slicing `[::-1]`** | `new_list = original[::-1]` | Tidak berubah |


List baru |

| **Metode `reverse()`** | `[Link]()` | **Berubah**


| `None` |

| **Fungsi `reversed()`** | `new_list = list(reversed(original))` | Tidak


berubah | Iterator → list baru |

**Contoh:**

```python

angka = [1, 2, 3, 4, 5]

# Slicing (aman untuk list asli)

terbalik1 = angka[::-1]

print(terbalik1) # [5, 4, 3, 2, 1]

# reverse() (modifikasi in-place)

[Link]()

print(angka) # [5, 4, 3, 2, 1] (asli berubah)

# reversed() + konversi ke list

angka = [1, 2, 3, 4, 5]

terbalik2 = list(reversed(angka))
print(terbalik2) # [5, 4, 3, 2, 1]

```

---

#### **2. Mengurutkan List (Sorting)**

Mengatur elemen list berdasarkan urutan tertentu


(ascending/descending).

**Metode Mengurutkan:**

| Metode | Contoh | Perubahan List Asli |


Parameter Kunci |

|-----------------------------|---------------------------------|---------------------|-----------------
--------------|

| **Metode `sort()`** | `[Link]()` | **Berubah** |


`key`, `reverse` |

| **Fungsi `sorted()`** | `new_list = sorted(original)` | Tidak berubah


| `key`, `reverse` |

**Parameter Penting:**

- `key`: Fungsi kustom untuk menentukan kriteria pengurutan

- `reverse`:

- `False` (default): Ascending (kecil → besar)

- `True`: Descending (besar → kecil)

**Contoh Pengurutan Dasar:**

```python

data = [3, 1, 4, 2, 5]

# sort() in-place (ubah asli)

[Link]()
print(data) # [1, 2, 3, 4, 5]

# sorted() (buat list baru)

data = [3, 1, 4, 2, 5]

data_baru = sorted(data, reverse=True)

print(data_baru) # [5, 4, 3, 2, 1]

```

---

### **Pengurutan Lanjutan dengan `key`**

#### a. Pengurutan Berdasarkan Atribut/Fungsi

```python

# Urutkan berdasarkan panjang string

buah = ["apel", "durian", "mangga", "kiwi"]

[Link](key=len)

print(buah) # ['apel', 'kiwi', 'mangga', 'durian']

# Urutkan berdasarkan huruf terakhir

def last_char(s):

return s[-1]

[Link](key=last_char)

print(buah) # ['durian', 'apel', 'kiwi', 'mangga']

```

#### b. Pengurutan Multi-Level

```python

# Urutkan berdasarkan nilai lalu nama


siswa = [

("Budi", 85),

("Ani", 90),

("Caca", 85)

# Level 1: Nilai (desc), Level 2: Nama (asc)

[Link](key=lambda x: (-x[1], x[0]))

print(siswa) # [('Ani', 90), ('Budi', 85), ('Caca', 85)]

```

#### c. Pengurutan Objek Kompleks

```python

class Produk:

def __init__(self, nama, harga):

[Link] = nama

[Link] = harga

produk = [

Produk("Laptop", 12000000),

Produk("Mouse", 150000),

Produk("Monitor", 3000000)

# Urutkan berdasarkan harga termahal dulu

[Link](key=lambda p: [Link], reverse=True)

for p in produk:

print(f"{[Link]}: Rp{[Link]:,}")

# Output:
# Laptop: Rp12,000,000

# Monitor: Rp3,000,000

# Mouse: Rp150,000

```

---

### **Perbedaan Penting: `sort()` vs `sorted()`**

| Fitur | `sort()` | `sorted()` |

|----------------------|------------------------------|-----------------------------|

| **Modifikasi asli** | Ya (in-place) | Tidak |

| **Return value** | `None` | List baru |

| **Tipe data input** | Hanya list | Semua iterable (tuple, set,


dll) |

| **Penggunaan memori**| Lebih efisien | Membuat salinan


|

---

### **Peringatan Penting**

1. **Tipe Data Campuran**:

```python

# Error saat mengurutkan tipe berbeda

campuran = [1, "dua", 3]

[Link]() # TypeError: '<' not supported between instances

```

2. **Case Sensitivity**:

```python

kata = ["Apel", "apel", "Mangga"]


[Link]() # ['Apel', 'Mangga', 'apel'] (urutan ASCII)

```

3. **Pengurutan Stabil**:

Python menjamin urutan relatif elemen dengan key sama


dipertahankan:

```python

data = [("A", 1), ("B", 1), ("C", 2)]

[Link](key=lambda x: x[1])

# [('A', 1), ('B', 1), ('C', 2)] → 'A' tetap sebelum 'B'

```

---

### **Optimasi Pengurutan**

- **Kompleksitas Waktu**: O(n log n) untuk sebagian besar kasus

- **Algoritma**: TimSort (hybrid merge + insertion sort)

- Untuk data besar (>1 juta elemen), pertimbangkan:

```python

import numpy as np # Pengurutan lebih cepat dengan NumPy

arr = [Link](0, 1000000, size=1000000)

[Link]()

```

---

### **Kesimpulan**

- **Membalik list**:

- Gunakan `[::-1]` untuk salinan terbalik


- Gunakan `.reverse()` untuk modifikasi langsung

- **Mengurutkan list**:

- Gunakan `.sort()` untuk efisiensi memori

- Gunakan `sorted()` untuk membuat salinan terurut

- **Kustomisasi**:

- Parameter `key` untuk kriteria kompleks

- Parameter `reverse` untuk urutan menurun

Dengan menguasai teknik ini, Anda dapat mengontrol urutan data sesuai
kebutuhan aplikasi! 🐍📊

- Iterasi List

### **Iterasi List dalam Python**

Iterasi list adalah proses mengakses setiap elemen dalam list secara
berurutan, satu per satu, untuk melakukan operasi tertentu (seperti
pemrosesan, perhitungan, atau modifikasi). Ini adalah konsep
fundamental dalam pemrograman Python dan dapat dilakukan dengan
berbagai cara:

---

#### **1. Metode Iterasi Dasar**

| Metode | Contoh Kode | Kelebihan


|

|----------------------------|--------------------------------------|-------------------------------|

| **Loop `for` Langsung** | `for item in list: ...` | Paling


sederhana dan intuitif |

| **Loop dengan Indeks** | `for i in range(len(list)): ...` | Akses indeks


dan nilai |

| **`enumerate()`** | `for i, item in enumerate(list): ...`| Akses


indeks & nilai sekaligus|
**Contoh:**

```python

buah = ["Apel", "Mangga", "Jeruk"]

# Cara 1: Akses elemen langsung

for b in buah:

print(f"Saya suka {b}")

# Cara 2: Akses via indeks

for i in range(len(buah)):

print(f"Buah #{i}: {buah[i]}")

# Cara 3: Pakai enumerate (rekomendasi)

for idx, nama in enumerate(buah, start=1):

print(f"Buah ke-{idx}: {nama}")

```

---

#### **2. Metode Lanjutan**

| Metode | Contoh Kode | Penggunaan


|

|----------------------------|--------------------------------------|-----------------------------|

| **List Comprehension** | `[expr for item in list]` | Pembuatan


list baru |

| **`map()`** | `list(map(fungsi, list))` | Aplikasi fungsi ke


tiap elemen |

| **`zip()`** | `for a,b in zip(list1, list2): ...` | Iterasi paralel dua


list |
| **`itertools`** | `import itertools` | Untuk iterasi
kompleks |

**Contoh:**

```python

# List Comprehension

kuadrat = [x**2 for x in [1, 2, 3, 4]] # [1, 4, 9, 16]

# map()

panjang = list(map(len, buah)) # [4, 6, 5] (panjang string)

# zip() - iterasi paralel

harga = [10000, 15000, 8000]

for b, h in zip(buah, harga):

print(f"{b}: Rp{h:,}")

# itertools - kombinasi

from itertools import combinations

for combo in combinations(buah, 2):

print(combo) # ('Apel','Mangga'), ('Apel','Jeruk'), ...

```

---

#### **3. Iterasi dengan Kondisi**

Filter elemen selama iterasi menggunakan `if`:

```python

# Hanya bilangan genap

angka = [1, 2, 3, 4, 5, 6]
genap = [x for x in angka if x % 2 == 0] # [2, 4, 6]

# Loop dengan break

for num in angka:

if num > 4:

break

print(num * 2) # Output: 2, 4, 6, 8

```

---

#### **4. Modifikasi List Selama Iterasi**

**Hati-hati!** Modifikasi ukuran list selama iterasi bisa menyebabkan bug:

```python

# ❌ Berbahaya: Hapus elemen selama iterasi

angka = [1, 2, 3, 4, 5]

for x in angka:

if x % 2 == 0:

[Link](x) # Hasil tak terduga!

# ✅ Solusi: Buat salinan atau gunakan list comprehension

angka = [x for x in angka if x % 2 != 0] # [1, 3, 5]

```

---

#### **5. Visualisasi Proses Iterasi**

```

List: [🍎, 🍌, 🍊]
Iterasi 1: b = 🍎 → proses

Iterasi 2: b = 🍌 → proses

Iterasi 3: b = 🍊 → proses

Selesai!

```

---

#### **6. Aplikasi Praktis**

1. **Analisis Data Sederhana:**

```python

nilai = [85, 92, 78, 90, 88]

rata_rata = sum(nilai) / len(nilai)

di_atas_rata = [n for n in nilai if n > rata_rata]

```

2. **Transformasi Data:**

```python

# Konversi suhu Celcius ke Fahrenheit

celcius = [0, 10, 20, 30]

fahrenheit = [(9/5)*c + 32 for c in celcius]

```

3. **Pencarian Elemen:**

```python

# Cari indeks pertama yang memenuhi kondisi

for idx, nilai in enumerate(nilai):

if nilai > 90:

print(f"Indeks: {idx}")
break

```

---

### **Peringatan Penting**

1. **Jangan modifikasi list** yang sedang diiterasi (kecuali dengan pola


khusus)

2. **Hindari nested loop** untuk list besar (kompleksitas O(n²))

3. **Gunakan generator** untuk menghemat memori pada data besar:

```python

# Generator expression (tidak langsung simpan di memori)

gen = (x**2 for x in range(1000000))

```

---

### **Kesimpulan**

Iterasi list adalah teknik untuk:

- Mengakses setiap elemen secara berurutan

- Memproses atau mentransformasi data

- Mencari, memfilter, atau menganalisis elemen

- Menggunakan pola seperti `for` loop, comprehension, atau fungsi


`map()`/`filter()`

Dengan menguasai iterasi, Anda dapat:

- Memproses kumpulan data apa pun

- Mengotomatiskan tugas berulang

- Membuat kode lebih efisien dan mudah dibaca


```python

# Filosofi Python

data = ["Belajar", "Iterasi", "List", "Python"]

for konsep in data:

print(f"{konsep} → 🚀", end=" ")

# Output: Belajar → 🚀 Iterasi → 🚀 List → 🚀 Python → 🚀

```

- Menghitung (Count)

### **Count List dalam Python**

"Count list" dalam Python umumnya mengacu pada dua konsep terkait
operasi penghitungan pada list:

1. **Metode `count()`** untuk menghitung kemunculan elemen spesifik.

2. **Fungsi `len()`** untuk menghitung jumlah total elemen.

Berikut penjelasan lengkapnya:

---

#### **1. Menghitung Jumlah Elemen Spesifik dengan `count()`**

Metode `[Link](x)` digunakan untuk menghitung berapa kali elemen


`x` muncul dalam list.

**Contoh:**

```python

angka = [1, 2, 3, 2, 4, 2, 5]

print([Link](2)) # Output: 3 (angka 2 muncul 3x)

print([Link](9)) # Output: 0 (tidak ada)


```

**Fitur Penting:**

- Pencarian **case-sensitive** untuk string

- Membandingkan elemen menggunakan **kesetaraan penuh** (`==`)

- Kompleksitas waktu **O(n)** (pencarian linear)

```python

kata = ["Python", "python", "PYTHON", "Java"]

print([Link]("python")) # Output: 1 (hanya cocok persis)

```

---

#### **2. Menghitung Total Elemen dengan `len()`**

Fungsi `len(list)` menghitung jumlah total elemen dalam list.

**Contoh:**

```python

buah = ["Apel", "Mangga", "Jeruk"]

print(len(buah)) # Output: 3

list_kosong = []

print(len(list_kosong)) # Output: 0

```

**Catatan:**

- Menghitung elemen utama (tidak menghitung elemen di dalam nested


list secara terpisah)
```python

nested = [[1, 2], [3, 4, 5]]

print(len(nested)) # Output: 2 (bukan 5)

```

---

### **Perbandingan `count()` vs `len()`**

| Fitur | `count(x)` | `len()` |

|------------------------|-------------------------------------|-----------------------------|

| **Tujuan** | Hitung kemunculan **elemen spesifik** | Hitung


**total elemen** |

| **Parameter** | Memerlukan input `x` (elemen) | Tidak perlu


parameter |

| **Return Value** | Jumlah kemunculan (`int`) | Panjang list


(`int`) |

| **Contoh** | `[1,2,2,3].count(2) → 2` | `len([1,2,3]) → 3`


|

---

### **Aplikasi Praktis**

#### a. Analisis Data Sederhana

```python

# Hitung frekuensi nilai

nilai = [85, 90, 78, 90, 85, 90, 78]

print(f"Frekuensi nilai 90: {[Link](90)}") # Output: 3

# Hitung persentase
total_siswa = len(nilai)

frekuensi_A = [Link](90)

print(f"Persentase nilai A: {frekuensi_A/total_siswa:.0%}") # Output: 43%

```

#### b. Validasi Input

```python

# Cek apakah ada duplikat

data_input = [1, 5, 3, 5, 8]

if any(data_input.count(x) > 1 for x in data_input):

print("Ada duplikat!")

```

#### c. Pemrosesan Teks

```python

kata = ["python", "java", "python", "c++", "python"]

print(f"'python' muncul {[Link]('python')} kali") # Output: 3 kali

```

---

### **Peringatan Penting**

1. **Tidak untuk Tipe Data Mutable**

`count()` tidak bisa mendeteksi elemen mutable seperti list/dict:

```python

list_nested = [[1,2], [3,4], [1,2]]

print(list_nested.count([1,2])) # Output: 2 (berhasil)

dict_list = [{"a":1}, {"b":2}, {"a":1}]


print(dict_list.count({"a":1})) # Output: 1 ❌ (hanya cocok dengan
instance pertama)

```

2. **Case Sensitivity**

```python

print(["A", "a"].count("a")) # Output: 1

```

3. **Performa untuk List Besar**

Gunakan `[Link]` untuk efisiensi:

```python

from collections import Counter

data_besar = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

counter = Counter(data_besar)

print(counter[3]) # Output: 3 (lebih cepat untuk banyak pencarian)

```

---

### **Alternatif untuk Kasus Kompleks**

#### Hitung elemen yang memenuhi kondisi:

```python

angka = [10, 15, 20, 25, 30]

# Hitung angka > 15 menggunakan comprehension

count = sum(1 for x in angka if x > 15)

print(count) # Output: 3

```
#### Hitung elemen dalam nested list:

```python

nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]

total_elemen = sum(len(sub) for sub in nested)

print(total_elemen) # Output: 9

```

---

### **Kesimpulan**

- **`count()`** → Hitung kemunculan **elemen spesifik**

Contoh: `[Link]("apel")`

- **`len()`** → Hitung **total elemen** dalam list

Contoh: `len(list)`

```python

# Contoh kombinasi

data = ["a", "b", "a", "c", "b", "a"]

print(f"Total elemen: {len(data)}") # Output: 6

print(f"Jumlah 'a': {[Link]('a')}") # Output: 3

```

Dua operasi ini adalah alat fundamental untuk analisis data dasar dalam
Python! 📊🐍

- Pemeriksaan `all()`/`any()`

### **Fungsi `all()` dan `any()` pada List di Python**


Fungsi `all()` dan `any()` digunakan untuk mengevaluasi kebenaran
(truthiness) sekumpulan nilai dalam iterable (seperti list). Berikut
penjelasan lengkapnya:

---

#### **1. Fungsi `all()`**

Mengembalikan `True` jika **semua elemen** dalam iterable bernilai


benar (truthy).

- Jika iterable kosong, mengembalikan `True`

**Contoh:**

```python

# Semua elemen True

print(all([True, 1, "data"])) # Output: True

# Ada satu elemen False (0)

print(all([True, 0, "data"])) # Output: False

# List kosong

print(all([])) # Output: True

```

---

#### **2. Fungsi `any()`**

Mengembalikan `True` jika **minimal satu elemen** dalam iterable


bernilai benar (truthy).

- Jika iterable kosong, mengembalikan `False`


**Contoh:**

```python

# Ada satu True

print(any([False, 0, "data"])) # Output: True

# Semua elemen False

print(any([False, 0, ""])) # Output: False

# List kosong

print(any([])) # Output: False

```

---

### **Konsep Truthy dan Falsy**

Nilai yang dianggap **falsy** (salah) dalam Python:

- `False`

- `None`

- Numerik nol: `0`, `0.0`, `0j`

- Sequence kosong: `""`, `[]`, `()`, `{}`

- `set()`, `range(0)`

**Selain itu dianggap truthy** (benar).

---

### **Aplikasi Praktis pada List**

#### a. Validasi Data


```python

# Cek apakah semua angka > 0

angka = [5, 2, 8, 10]

if all(x > 0 for x in angka):

print("Semua bilangan positif")

# Cek apakah ada angka genap

if any(x % 2 == 0 for x in angka):

print("Ada angka genap")

```

#### b. Pengecekan Kondisi Kompleks

```python

# Validasi password:

# - Minimal 8 karakter

# - Mengandung huruf besar

# - Mengandung angka

password = "P@ssw0rd"

kondisi = [

len(password) >= 8,

any([Link]() for c in password),

any([Link]() for c in password)

if all(kondisi):

print("Password valid!")

```

#### c. Pemrosesan Dataset


```python

data = [

{"nama": "Andi", "nilai": 80},

{"nama": "Budi", "nilai": 65},

{"nama": "Caca", "nilai": None} # Data invalid

# Cek apakah semua data nilai valid

if all(d["nilai"] is not None for d in data):

print("Semua data lengkap")

else:

print("Ada data yang hilang") # Output ini

```

---

### **Perbedaan Krusial**

| Scenario | `all()` | `any()` |

|-------------------|-----------------------------------|-----------------------------------|

| **List Kosong** | `True` | `False` |

| **Semua True** | `True` | `True` |

| **Semua False** | `False` | `False` |

| **Minimal Satu True**| `False` (jika ada False) | `True`


|

| **Minimal Satu False**| `False` | `True` (jika ada True)


|

---

### **Optimasi dengan Short-Circuit**


Python berhenti mengevaluasi segera setelah hasil pasti diketahui:

- `all()`: Berhenti di elemen **pertama** yang falsy

- `any()`: Berhenti di elemen **pertama** yang truthy

**Contoh:**

```python

def test(x):

print(f"Evaluasi {x}")

return x

all(test(x) for x in [1, 0, 2])

# Output:

# Evaluasi 1

# Evaluasi 0 → Berhenti

any(test(x) for x in [0, False, 3])

# Output:

# Evaluasi 0

# Evaluasi False

# Evaluasi 3 → Berhenti

```

---

### **Kombinasi dengan Generator Expression**

Gunakan generator untuk menghemat memori pada data besar:

```python

# File besar: cek apakah semua baris valid

with open("[Link]") as file:


if all([Link]("OK") for line in file):

print("Semua baris valid")

```

---

### **Kesalahan Umum**

1. **Kesalahan logika**:

```python

# SALAH: Ini memeriksa kebenaran list, bukan elemennya

kondisi = [x > 0 for x in [-1, 0, 5]]

print(all(kondisi)) # False (benar)

print(all(kondisi) is False) # Tapi mungkin bukan yang diinginkan

```

2. **Penggunaan dengan tipe non-boolean**:

```python

# List angka: 0=False, selainnya=True

print(all([1, 2, 3])) # True

print(all([1, 0, 3])) # False

```

---

### **Kesimpulan**

- **`all()`** → Gerbang logika **AND** untuk seluruh elemen list

- **`any()`** → Gerbang logika **OR** untuk seluruh elemen list

```python
# Analogi elektronik

AND_gate = all([input1, input2, input3])

OR_gate = any([input1, input2, input3])

```

Fungsi ini sangat powerful untuk:

- Validasi data

- Filtering kondisi

- Pemeriksaan kualitas data

- Logika bisnis kompleks

Dengan memahami `all()` dan `any()`, kode Python Anda akan menjadi
lebih elegan dan efisien! 🐍✨

- List Comprehension

### **List Comprehension dalam Python**

**List comprehension** adalah fitur Python yang memungkinkan


pembuatan list baru dengan sintaks yang **ringkas, ekspresif, dan
efisien** dari iterable yang sudah ada. Fitur ini menggabungkan proses
*looping*, *filtering*, dan *transformasi* dalam satu baris kode.

---

#### **Struktur Dasar**

```python

[expression for item in iterable if condition]

```

- **`expression`**: Operasi/transformasi pada setiap item

- **`for item in iterable`**: Loop melalui iterable (list, range, dll)


- **`if condition`** (opsional): Filter item berdasarkan kondisi

---

### **4 Jenis Utama List Comprehension**

#### **1. Transformasi Sederhana**

```python

# Kuadrat bilangan 0-9

kuadrat = [x**2 for x in range(10)]

print(kuadrat) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

```

#### **2. Transformasi dengan Kondisi**

```python

# Hanya bilangan genap

genap = [x for x in range(10) if x % 2 == 0]

print(genap) # [0, 2, 4, 6, 8]

# Konversi ke huruf besar untuk string > 3 karakter

buah = ["apel", "kiwi", "mangga"]

besar = [[Link]() for b in buah if len(b) > 3]

print(besar) # ['APEL', 'MANGG']

```

#### **3. Kondisi If-Else**

```python

# Ganjil: negatif, Genap: kuadrat

transform = [x**2 if x % 2 == 0 else -x for x in range(1, 6)]


print(transform) # [-1, 4, -3, 16, -5]

```

#### **4. Nested Loop**

```python

# Kombinasi kartu

jenis = ["Hati", "Sekop"]

angka = ["As", "2", "3"]

kartu = [(j, a) for j in jenis for a in angka]

# Output: [('Hati','As'), ('Hati','2'), ...]

```

---

### **Vs. Loop Konvensional**

**Kode tanpa comprehension:**

```python

hasil = []

for x in range(10):

if x % 2 == 0:

[Link](x**2)

```

**Kode dengan comprehension:**

```python

hasil = [x**2 for x in range(10) if x % 2 == 0]

```

Keuntungan: **Lebih ringkas, mudah dibaca, dan sering lebih cepat**!


---

### **Aplikasi Praktis**

#### a. Matriks Transpose

```python

matriks = [[1, 2], [3, 4], [5, 6]]

transpose = [[row[i] for row in matriks] for i in range(2)]

# [[1, 3, 5], [2, 4, 6]]

```

#### b. Flatten Nested List

```python

nested = [[1, 2], [3, 4, 5], [6]]

flat = [num for sublist in nested for num in sublist]

# [1, 2, 3, 4, 5, 6]

```

#### c. Pembersihan Data

```python

input_data = [" Python ", " 123 ", "", "Data"]

bersih = [[Link]() for s in input_data if [Link]()]

# ['Python', '123', 'Data']

```

---

### **Peringatan Penting**

1. **Hindari kompleksitas berlebihan**:


```python

# ❌ Sulit dibaca

[x for x in [y for y in range(10)] if x % 2 == 0]

# ✅ Bagi menjadi dua tahap

genap = [x for x in range(10) if x % 2 == 0]

```

2. **Jangan gunakan untuk efek samping**:

```python

# ❌ Tidak disarankan (efek samping print)

[print(x) for x in range(5)]

# ✅ Gunakan loop biasa

for x in range(5):

print(x)

```

3. **Perhatikan penggunaan memori** untuk data besar (gunakan


generator jika perlu):

```python

# Generator expression (menghemat memori)

gen = (x**2 for x in range(1000000))

```

---

### **Perbandingan Performa**

```python
# List comprehension

%%timeit

[x**2 for x in range(1000) if x % 2 == 0]

# Loop tradisional

%%timeit

hasil = []

for x in range(1000):

if x % 2 == 0:

[Link](x**2)

```

**Hasil**: List comprehension **30-50% lebih cepat** untuk operasi


dasar!

---

### **Kapan Tidak Menggunakan?**

1. Ketika logika terlalu kompleks (gunakan fungsi terpisah)

2. Saat membutuhkan `try-except` dalam transformasi

3. Untuk operasi I/O atau fungsi dengan efek samping

4. Jika hasil tidak perlu disimpan (misal hanya untuk iterasi)

---

### **Filosofi Python**

> "Flat is better than nested."

> — The Zen of Python

List comprehension mendukung filosofi ini dengan:


- Mengurangi nesting loop

- Menyederhanakan logika

- Meningkatkan keterbacaan

---

### **Kesimpulan**

List comprehension cocok untuk:

```python

# Transformasi data

[transform(item) for item in iterable]

# Filtering data

[item for item in iterable if condition]

# Kombinasi transformasi + filtering

[transform(item) for item in iterable if condition]

```

Dengan menguasai teknik ini, Anda bisa:

1. Menulis kode lebih efisien

2. Meningkatkan keterbacaan

3. Mengoptimalkan performa

4. Mengekspresikan logika secara elegan

```python

# Analogi kreatif

seni_koding = [ide for ide in otak if [Link]]

```
- **Tuple**

- Pembuatan Tuple

### **Pembuatan Tuple dalam Python**

**Tuple** adalah struktur data Python yang menyimpan koleksi **terurut


(ordered)** dan **immutable (tidak dapat diubah)**. Berbeda dengan list
yang mutable, tuple tidak bisa dimodifikasi setelah dibuat. Tuple umum
digunakan untuk menyimpan data terkait yang tidak boleh berubah.

---

### **4 Cara Membuat Tuple**

#### 1. **Menggunakan Tanda Kurung `()`**

```python

# Tuple kosong

kosong = ()

# Tuple dengan satu elemen (harus ada koma!)

satu_elemen = (42,)

# Tuple standar

warna = ("merah", "hijau", "biru")

```

#### 2. **Tanpa Tanda Kurung (Tuple Packing)**

```python

point = 10, 20, 30

print(point) # Output: (10, 20, 30)


```

#### 3. **Menggunakan Konstruktor `tuple()`**

```python

# Dari list

list_angka = [1, 2, 3]

tuple_angka = tuple(list_angka) # (1, 2, 3)

# Dari string

tuple_char = tuple("Python") # ('P','y','t','h','o','n')

```

#### 4. **Tuple Bersarang (Nested Tuple)**

```python

matrix = ((1, 2), (3, 4), (5, 6))

```

---

### **Ciri Khas Tuple**

| Karakteristik | Contoh | Keterangan |

|--------------|--------|------------|

| **Immutable** | `warna[0] = "kuning"` | Error: Tidak bisa diubah |

| **Ordered** | `print(warna[1])` | Akses elemen dengan indeks |

| **Heterogen** | `data = (1, "teks", True)` | Bisa campur tipe data |

| **Bisa Duplikat** | `(1, 1, 2)` | Elemen boleh sama |

---
### **Perbandingan Tuple vs List**

| Fitur | Tuple | List |

|-------|-------|------|

| **Mutabilitas** | ❌ Immutable | ✅ Mutable |

| **Sintaks** | `()` atau tanpa kurung | `[]` |

| **Performa** | ⚡ Lebih cepat | ⏳ Lebih lambat |

| **Penggunaan** | Data konstan (koordinat, konfigurasi) | Data dinamis


(koleksi yang berubah) |

| **Keamanan** | ✔️Aman untuk kunci dictionary | ❌ Tidak bisa jadi kunci


dict |

---

### **Contoh Praktis**

1. **Mengembalikan Multiple Value dari Fungsi**

```python

def hitung(a, b):

return a+b, a*b # Otomatis jadi tuple

hasil = hitung(3, 4)

print(hasil) # (7, 12)

```

2. **Pertukaran Nilai (Swap)**

```python

a, b = 5, 10

a, b = b, a # Pertukaran via tuple packing/unpacking

print(f"a={a}, b={b}") # a=10, b=5

```
3. **Kunci Dictionary**

```python

lokasi = {

(35.68, 139.69): "Tokyo",

(40.71, -74.00): "New York"

print(lokasi[(40.71, -74.00)]) # "New York"

```

---

### **Operasi Dasar Tuple**

1. **Akses Elemen** (Sama seperti list)

```python

data = (10, 20, 30)

print(data[1]) # 20

```

2. **Slicing**

```python

print(data[1:]) # (20, 30)

```

3. **Concatenation**

```python

gabung = (1, 2) + (3, 4) # (1, 2, 3, 4)

```

4. **Repetisi**
```python

ulang = ("Hi",) * 3 # ('Hi', 'Hi', 'Hi')

```

---

### **Mengapa Menggunakan Tuple?**

1. **Keamanan Data**: Memastikan data tetap konsisten

2. **Optimasi Memori**: Lebih hemat 20-30% dibanding list

3. **Validasi Alami**: Memaksa programmer tidak mengubah data

4. **Kompatibilitas**: Bisa digunakan sebagai kunci dictionary

```python

# Contoh performa (ukuran memori)

import sys

list_size = [Link]([1,2,3]) # ~88 bytes

tuple_size = [Link]((1,2,3)) # ~64 bytes

```

---

### **Kapan Memilih Tuple vs List?**

- Gunakan **Tuple** untuk:

- Koleksi nilai konstan (hari, bulan)

- Kembalian fungsi multiple value

- Kunci dictionary

- Gunakan **List** untuk:

- Koleksi yang perlu dimodifikasi

- Stack/queue operations
- Data yang perlu diurutkan/diubah

---

### **Filosofi Python**

> _"There should be one—and preferably only one—obvious way to do


it."_

> — The Zen of Python

Tuple dan List ada untuk tujuan berbeda:

- **List**: Koleksi **homogen** yang berubah

- **Tuple**: Koleksi **heterogen** yang tetap

---

### **Kesimpulan**

Pembuatan tuple adalah cara menyimpan data:

1. **Immutable**: Tidak bisa diubah setelah dibuat

2. **Efisien**: Lebih cepat dan hemat memori

3. **Multiguna**: Ideal untuk data konstan dan operasi packing/unpacking

```python

# Analogi kreatif

koordinat_planet = ( # Data astronomi tetap

("Merkurius", 57.9, 0.24),

("Venus", 108.2, 0.62),

("Bumi", 149.6, 1.00)

```
- Pengindeksan & Pemotongan

### **Indexing dan Slicing Tuple dalam Python**

Tuple adalah struktur data **terurut (ordered)** dan **immutable** di


Python. Indexing dan slicing adalah operasi dasar untuk mengakses
elemen tuple berdasarkan posisinya. Berikut penjelasan lengkapnya:

---

#### **1. Indexing (Pengindeksan)**

Mengakses elemen tunggal menggunakan posisi indeksnya.

- Indeks dimulai dari **0** untuk elemen pertama

- Indeks negatif dimulai dari **-1** untuk elemen terakhir

**Contoh:**

```python

warna = ("merah", "hijau", "biru", "kuning", "ungu")

# Indeks positif

print(warna[0]) # Output: "merah"

print(warna[2]) # Output: "biru"

# Indeks negatif

print(warna[-1]) # Output: "ungu"

print(warna[-3]) # Output: "biru"

```

**Visualisasi Indeks:**

```
Indeks Positif: 0 1 2 3 4

┌──────┬───────┬───────┬─────────┬───────┐

Elemen: │ merah│ hijau │ biru │ kuning │ ungu │

└──────┴───────┴───────┴─────────┴───────┘

Indeks Negatif: -5 -4 -3 -2 -1

```

---

#### **2. Slicing (Pemotongan)**

Mengambil sub-tuple berdasarkan rentang indeks dengan format:

```python

tuple[start:stop:step]

```

- **start**: Indeks awal (inklusif), default = 0

- **stop**: Indeks akhir (eksklusif), default = akhir tuple

- **step**: Interval loncatan, default = 1

**Contoh:**

```python

angka = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

# Rentang dasar

print(angka[2:5]) # (2, 3, 4) [indeks 2-4]

print(angka[:4]) # (0, 1, 2, 3) [awal s.d indeks 3]

print(angka[6:]) # (6, 7, 8, 9) [indeks 6 s.d akhir]

# Step loncatan

print(angka[::2]) # (0, 2, 4, 6, 8) [loncat 2]


print(angka[1:8:3]) # (1, 4, 7) [indeks 1,4,7]

# Indeks negatif

print(angka[-4:-1]) # (6, 7, 8) [indeks -4 s.d -2]

print(angka[::-1]) # (9,8,7,6,5,4,3,2,1,0) [reverse]

```

---

### **Perbedaan Tuple vs List dalam Indexing/Slicing**

| Operasi | Tuple | List |

|------------------|-------------------------------------------|----------------------------------------
---|

| **Indexing** | `nilai = tuple[2]` (bisa baca, tidak bisa ubah) | `list[2] =


nilai` (bisa baca dan ubah) |

| **Slicing** | Hasil: **tuple baru** | Hasil: **list baru**


|

| **Mutabilitas** | ❌ Tidak bisa modifikasi setelah dibuat | ✅ Bisa


modifikasi |

**Contoh Error Mutabilitas:**

```python

data = (10, 20, 30)

data[1] = 99 # TypeError: 'tuple' object does not support item


assignment

```

---

### **Aplikasi Praktis**

#### 1. Ekstrak Data Terstruktur


```python

koordinat = (35.68, 139.69, "Tokyo", "Jepang")

latitude = koordinat[0] # 35.68

kota = koordinat[2] # "Tokyo"

```

#### 2. Reverse Data

```python

kode = ("A", "B", "C", "D")

kode_terbalik = kode[::-1] # ('D','C','B','A')

```

#### 3. Partisi Data

```python

tanggal = (2024, 4, 15)

# Ambil tahun dan bulan

periode = tanggal[:2] # (2024, 4)

```

#### 4. Sistem Grid

```python

grid = (

(1, 2, 3),

(4, 5, 6),

(7, 8, 9)

# Ambil baris pertama

baris1 = grid[0] # (1, 2, 3)


# Ambil kolom pertama

kolom1 = (row[0] for row in grid) # Generator: (1, 4, 7)

```

---

### **Peringatan Penting**

1. **Indeks di Luar Rentang**

```python

data = (10, 20)

print(data[2]) # IndexError: tuple index out of range

```

2. **Slicing Aman untuk Indeks Tidak Valid**

```python

print(data[0:10]) # (10, 20) (otomatis disesuaikan)

```

3. **Step Nol Tidak Diizinkan**

```python

print(data[::0]) # ValueError: slice step cannot be zero

```

---

### **Optimasi dengan Slicing**

Karena tuple **immutable**, slicing sangat efisien:

- Tidak membuat salinan elemen, hanya referensi baru ke tuple asli

- Operasi O(1) untuk waktu konstan


```python

besar = (0,)*1000000 # Tuple 1 juta elemen

subset = besar[999990:] # Sangat cepat (10 elemen terakhir)

```

---

### **Kesimpulan**

1. **Indexing**

- Akses elemen tunggal dengan `tuple[index]`

- Dukung indeks positif dan negatif

2. **Slicing**

- Format: `tuple[start:stop:step]`

- Hasil: tuple baru

- Fitur khusus: reverse (`[::-1]`), loncatan (`[::2]`)

3. **Perilaku Khusus Tuple**

- Tidak bisa diubah setelah dibuat

- Slicing selalu menghasilkan tuple baru

- Lebih efisien daripada list untuk data tetap

```python

# Analogi kreatif

buku = ("Prolog", "Isi", "Epilog") # Bab buku

halaman_utama = buku[1] # "Isi"

cuplikan = buku[0:2] # ("Prolog", "Isi")

```
- Ubah/Hapus Item (*Imutabel*)

### **Mengubah dan Menghapus Item Tuple dalam Python: Realitas dan
Solusi**

Tuple bersifat **immutable (tidak dapat diubah)**, artinya Anda **tidak


bisa** mengubah, menambah, atau menghapus elemen individual setelah
tuple dibuat. Upaya langsung akan menyebabkan error. Namun, ada solusi
kreatif untuk mencapai efek serupa:

---

### ❌ **Cara Langsung (Gagal)**

```python

data = (10, 20, 30, 40)

# Ubah elemen

data[1] = 99 # TypeError: 'tuple' object does not support item


assignment

# Hapus elemen

del data[0] # TypeError: 'tuple' object doesn't support item deletion

```

---

### ✅ **Solusi untuk "Mengubah" Tuple**

#### 1. **Buat Tuple Baru dengan Slicing + Concatenation**

```python

data = (10, 20, 30, 40)


# Ubah elemen indeks 1 (20 → 99)

data_baru = data[:1] + (99,) + data[2:]

print(data_baru) # (10, 99, 30, 40)

```

#### 2. **Konversi ke List → Ubah → Kembali ke Tuple**

```python

data = (10, 20, 30, 40)

list_data = list(data)

list_data[1] = 99 # Ubah elemen

data_baru = tuple(list_data)

print(data_baru) # (10, 99, 30, 40)

```

---

### ✅ **Solusi untuk "Menghapus" Elemen**

#### 1. **Slicing + Concatenation (Hapus Elemen Indeks 1)**

```python

data = (10, 20, 30, 40)

data_baru = data[:1] + data[2:]

print(data_baru) # (10, 30, 40)

```

#### 2. **Filter Elemen (Hapus Berdasarkan Nilai)**

```python

data = (10, 20, 30, 40)

data_baru = tuple(x for x in data if x != 20)

print(data_baru) # (10, 30, 40)


```

---

### 💡 **Hapus Seluruh Tuple (Mungkin!)**

Meskipun elemen tak bisa dihapus, Anda bisa menghapus **variabel


tuple**-nya:

```python

data = (1, 2, 3)

del data # Hapus variabel 'data' dari memori

print(data) # NameError: name 'data' is not defined

```

---

### **Mengapa Immutable?**

1. **Keamanan Data**: Memastikan data tetap konsisten

2. **Optimasi**: Lebih efisien dalam memori dan performa

3. **Valid Hash**: Bisa jadi kunci dictionary

```python

lokasi = {(35.68, 139.69): "Tokyo"} # Tuple sebagai kunci

```

---

### **Kapan Menggunakan Trik Ini?**

| Skenario | Rekomendasi Solusi |

|---------------------------|----------------------------------------|

| Modifikasi jarang | Buat tuple baru dengan slicing |


| Banyak modifikasi | Konversi ke list, lalu balik ke tuple |

| Hapus beberapa elemen | Filter dengan generator expression |

| Struktur data dinamis | Pertimbangan gunakan **list** saja |

---

### **Perbandingan Performa**

```python

import timeit

# Metode Slicing

[Link]('data[:1] + (99,) + data[2:]', setup='data=(1,2,3,4)')

# Output: ~0.1 detik (juta iterasi)

# Metode Konversi List

[Link]('t = list(data); t[1]=99; tuple(t)', setup='data=(1,2,3,4)')

# Output: ~0.3 detik (juta iterasi) - Lebih lambat!

```

---

### **Best Practice**

1. **Hindari modifikasi berlebihan** - Jika sering ubah/hapus, gunakan


**list**.

2. **Manfaatkan immutability** untuk data konstan:

```python

# Data yang tak berubah (hari dalam seminggu)

HARI = ("Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu")

```
3. **Gunakan tuple unpacking** untuk "ekstrak dan abaikan":

```python

data = (10, 20, 30, 40)

pertama, *_, terakhir = data # _ menampung [20,30]

print(pertama, terakhir) # 10 40

```

---

### **Kesimpulan**

- **Tuple immutable**: Tidak bisa ubah/hapus elemen individual secara


langsung.

- **Solusi tidak langsung**:

- Buat tuple baru dengan elemen yang diinginkan (via slicing,


concatenation)

- Konversi sementara ke list untuk modifikasi kompleks

- **Alternatif**: Gunakan list jika butuh struktur data mutable.

> "Python: When you need immutability, use a tuple; when you need
mutability, use a list."

> — Prinsip Desain Python

Contoh akhir:

```python

# Data asli tetap aman

original = (1, 2, 3, 4)

# "Hapus" elemen kedua (2)

modified = original[:1] + original[2:]


print(original) # (1, 2, 3, 4) → tidak berubah!

print(modified) # (1, 3, 4)

```

- Iterasi Tuple

### **Iterasi Tuple dalam Python**

Iterasi tuple adalah proses mengakses setiap elemen dalam tuple secara
berurutan, satu per satu, untuk melakukan operasi tertentu (seperti
membaca, memproses, atau menghitung). Karena tuple bersifat
**immutable** (tidak bisa diubah), iterasi umumnya digunakan untuk
**membaca data** atau **mentransformasikannya** menjadi struktur
data lain.

---

### **4 Metode Iterasi Tuple**

#### 1. **Loop `for` Langsung**

Mengakses elemen tuple tanpa indeks:

```python

warna = ("merah", "hijau", "biru")

for w in warna:

print(f"Warna: {w}")

```

**Output:**

```

Warna: merah

Warna: hijau

Warna: biru

```
#### 2. **Loop dengan Indeks (`range()`)**

Mengakses elemen melalui indeks:

```python

for i in range(len(warna)):

print(f"Indeks {i}: {warna[i]}")

```

**Output:**

```

Indeks 0: merah

Indeks 1: hijau

Indeks 2: biru

```

#### 3. **Loop dengan `enumerate()`**

Mendapatkan indeks dan nilai sekaligus:

```python

for idx, nilai in enumerate(warna):

print(f"Elemen {idx} = {nilai}")

```

**Output:**

```

Elemen 0 = merah

Elemen 1 = hijau

Elemen 2 = biru

```

#### 4. **While Loop**

Iterasi manual dengan kontrol indeks:


```python

i=0

while i < len(warna):

print(warna[i])

i += 1

```

---

### **Aplikasi Praktis Iterasi Tuple**

#### 1. **Agregasi Data**

```python

nilai = (85, 92, 78, 90)

total = 0

for n in nilai:

total += n

print(f"Rata-rata: {total/len(nilai)}") # Output: Rata-rata: 86.25

```

#### 2. **Pencarian Elemen**

```python

if "hijau" in warna:

print("Hijau ada dalam tuple") # Output: Hijau ada dalam tuple

```

#### 3. **Transformasi ke Struktur Lain**

```python

# Konversi ke list

list_warna = [[Link]() for w in warna] # ['MERAH', 'HIJAU', 'BIRU']


# Konversi ke dictionary

dict_warna = {idx: w for idx, w in enumerate(warna)}

# {0: 'merah', 1: 'hijau', 2: 'biru'}

```

#### 4. **Multi-dimensional Tuple**

```python

matrix = ((1, 2), (3, 4), (5, 6))

for row in matrix:

for num in row:

print(num, end=" ")

print()

```

**Output:**

```

12

34

56

```

---

### **Keuntungan Iterasi Tuple vs List**

| Fitur | Tuple | List |

|----------------|--------------------------------------|---------------------|

| **Keamanan** | ✅ Data tidak bisa diubah saat iterasi | ❌ Risiko


modifikasi tak terduga |

| **Performa** | ⚡ Lebih cepat (optimasi Python) | ⏳ Lebih lambat |


| **Memori** | Lebih hemat | Lebih boros |

---

### **Peringatan Penting**

1. **Jangan coba mengubah elemen** selama iterasi:

```python

for w in warna:

w = "ungu" # ❌ Tidak memengaruhi tuple asli!

print(warna) # Tetap ('merah', 'hijau', 'biru')

```

2. **Hindari nested loop untuk tuple besar** (kompleksitas O(n²)).

---

### **Optimasi dengan Fungsi Bawaan**

#### a. **`map()`** untuk transformasi

```python

panjang = tuple(map(len, warna)) # (5, 5, 4)

```

#### b. **`filter()`** untuk seleksi

```python

angka = (10, 15, 20, 25)

genap = tuple(filter(lambda x: x % 2 == 0, angka)) # (10, 20)

```

#### c. **`zip()`** untuk iterasi paralel


```python

english = ("red", "green", "blue")

indonesian = ("merah", "hijau", "biru")

for e, i in zip(english, indonesian):

print(f"{e} = {i}")

```

**Output:**

```

red = merah

green = hijau

blue = biru

```

---

### **Kapan Menggunakan Iterasi Tuple?**

1. Saat bekerja dengan **data konstan** (koordinat, konfigurasi)

2. Untuk **kunci dictionary** kompleks yang perlu diiterasi

3. Ketika membutuhkan **jaminan data tidak berubah** selama


pemrosesan

4. Pada operasi **I/O** (misal: membaca data dari database)

```python

# Contoh: Data sensor yang fixed

sensor_data = (25.5, 60.2, 1024.7)

for value in sensor_data:

if value > 100:

print(f"Peringatan: {value} melebihi batas!")


```

---

### **Kesimpulan**

Iterasi tuple adalah teknik fundamental untuk:

- Mengakses elemen tuple secara berurutan

- Membaca data tanpa modifikasi

- Mentransformasikan tuple ke struktur data lain

- Menjaga integritas data selama pemrosesan

```python

# Filosofi Python

prinsip = (

"Readability counts",

"Explicit is better than implicit",

"Simple is better than complex"

for ide in prinsip:

print(f"Python: {ide}")

```

> **Catatan**: Meskipun tuple immutable, iterasi tetap powerful untuk


operasi baca dan transformasi!

- Menghitung (Count)

- Keanggotaan (Membership)

- Posisi Indeks (Index Position)

- Pengurutan (Sorting)
- **Set**

- Pembuatan Set

### **Pembuatan Set dalam Python**

**Set** adalah struktur data Python yang menyimpan koleksi **unik (tidak
ada duplikat)**, **tidak terurut (unordered)**, dan **mutable (dapat
diubah)**. Set sangat efisien untuk operasi keanggotaan (membership
testing) dan penghapusan duplikat.

---

### **3 Cara Membuat Set**

#### 1. **Menggunakan Kurung Kurawal `{}`**

```python

# Set dengan elemen

buah = {"apel", "mangga", "jeruk"}

print(buah) # Output acak: {'jeruk', 'apel', 'mangga'} (unordered)

# Set kosong? Hati-hati!

kosong = {} # ❌ Ini membuat dictionary, bukan set!

print(type(kosong)) # <class 'dict'>

```

#### 2. **Menggunakan Konstruktor `set()`**

```python

# Set dari list (otomatis hapus duplikat)

angka = set([1, 2, 2, 3, 3])

print(angka) # {1, 2, 3}
# Set kosong yang benar

kosong = set()

print(type(kosong)) # <class 'set'>

# Set dari string (pecah karakter unik)

huruf_unik = set("Python") # {'P', 'y', 't', 'h', 'o', 'n'}

```

#### 3. **Set Comprehension**

```python

# Set bilangan genap 0-9

genap = {x for x in range(10) if x % 2 == 0}

print(genap) # {0, 2, 4, 6, 8}

# Huruf unik dalam list kata

kata = ["apple", "banana", "cherry"]

huruf_awal = {k[0] for k in kata} # {'a', 'b', 'c'}

```

---

### **Ciri Khas Set**

| Karakteristik | Contoh | Keterangan |

|---------------|--------|------------|

| **Unordered** | `print(set([1,2,3]))` | Urutan acak (tidak bisa diindeks) |

| **Unik** | `{1,1,2,2} → {1,2}` | Duplikat otomatis dihapus |

| **Mutable** | `[Link](4)` | Bisa tambah/hapus elemen |

| **Elemen Immutable** | `s = {1, "text", (1,2)}` | Tidak bisa berisi list/set


|
---

### **Operasi Dasar Set**

#### 1. Tambah Elemen

```python

s = {1, 2}

[Link](3) # {1, 2, 3}

[Link]([4,5]) # {1, 2, 3, 4, 5} (dari iterable)

```

#### 2. Hapus Elemen

```python

s = {1, 2, 3, 4}

[Link](3) # {1, 2, 4} (error jika elemen tidak ada)

[Link](99) # {1, 2, 4} (aman jika tidak ada)

[Link]() # Hapus elemen acak (misal: 1 → {2,4})

[Link]() # set() (kosong)

```

#### 3. Cek Keanggotaan

```python

print(2 in s) # True

```

---

### **Perbandingan Set vs List**

| Fitur | Set | List |


|-------|-----|------|

| **Urutan** | ❌ Tidak terurut | ✅ Terurut |

| **Duplikat** | ❌ Tidak diizinkan | ✅ Diizinkan |

| **Akses Indeks** | ❌ Tidak bisa | ✅ Bisa |

| **Kecepatan Cek Anggota** | ⚡ O(1) (super cepat) | 🐢 O(n) (lambat) |

| **Penggunaan Memori** | Lebih besar | Lebih kecil |

---

### **Aplikasi Praktis**

1. **Hapus Duplikat dari List**

```python

data = [1, 2, 2, 3, 4, 4, 4]

unik = list(set(data)) # [1, 2, 3, 4] (urutan mungkin berubah)

```

2. **Cek Irisan Data (Shared Items)**

```python

admin = {"Alice", "Bob", "Charlie"}

online = {"Bob", "David", "Alice"}

# User online yang admin

both = admin & online # {'Alice', 'Bob'}

```

3. **Validasi Keunikan Data**

```python

username = ["budi", "ani", "budi"]

if len(username) != len(set(username)):
print("Ada username duplikat!")

```

---

### **Operasi Himpunan (Set Operations)**

| Operasi | Simbol | Metode | Contoh |

|---------|--------|--------|--------|

| **Union** | ` | ` | `union()` | `A | B` |

| **Intersection** | `&` | `intersection()` | `A & B` |

| **Difference** | `-` | `difference()` | `A - B` |

| **Symmetric Diff** | `^` | `symmetric_difference()` | `A ^ B` |

```python

A = {1,2,3}; B = {3,4,5}

print(A | B) # {1,2,3,4,5} (gabungan)

print(A & B) # {3} (irisan)

print(A - B) # {1,2} (di A tapi tidak di B)

print(A ^ B) # {1,2,4,5} (yang tidak ada di kedua)

```

---

### **FrozenSet: Versi Immutable**

```python

# Set yang tidak bisa diubah (immutable)

fs = frozenset([1,2,3])

[Link](4) # AttributeError
# Bisa jadi kunci dictionary

kamus = {fs: "data angka"}

```

---

### **Peringatan Penting**

1. **Urutan Acak**:

```python

print({1,2,3} == {3,2,1}) # True (urutan tidak berpengaruh)

```

2. **Tidak Support Indexing**:

```python

s = {10,20,30}

print(s[0]) # TypeError: 'set' object is not subscriptable

```

3. **Elemen Harus Hashable**:

```python

{{1,2}: "value"} # TypeError: unhashable type: 'set'

```

---

### **Kesimpulan**

Set ideal untuk:

```python

# 1. Penyimpanan data unik


unique_ids = {101, 102, 103, 101} # {101,102,103}

# 2. Uji keanggotaan cepat

if user_id in valid_ids: # ⚡ O(1)

# 3. Operasi himpunan matematis

solusi = set_A - (set_B | set_C)

```

> **Filosofi Python**:

> _"When you have unique, unordered data, sets are your best friend."_

Dengan memahami set, Anda bisa menulis kode lebih efisien untuk
masalah yang melibatkan keunikan dan relasi himpunan! 🐍🔍

- Iterasi Set

### **Iterasi Set dalam Python**

Iterasi set adalah proses mengakses setiap elemen dalam set secara
berurutan satu per satu. Karena set bersifat **tidak terurut (unordered)**
dan **tidak dapat diindeks**, iterasi menjadi cara utama untuk
memproses elemen-elemennya. Berikut penjelasan lengkapnya:

---

### **Karakteristik Kunci Iterasi Set**

1. **Urutan Acak**

Elemen muncul dalam urutan tidak tetap (tergantung struktur hash


internal)

```python

for item in {1, 2, 3}:


print(item) # Output: 1, 2, 3 (urutan bisa berbeda di lingkungan lain)

```

2. **Tidak Ada Duplikat**

Setiap elemen hanya diakses sekali

```python

for char in set("banana"):

print(char) # Output: 'b', 'a', 'n' (tanpa duplikat)

```

3. **Elemen Immutable**

Elemen set harus hashable (tidak bisa berisi list/set)

```python

valid = {1, "text", (1, 2)}

invalid = {[1, 2]} # TypeError: unhashable type

```

---

### **3 Metode Iterasi Set**

#### 1. Loop `for` Langsung (Paling Umum)

```python

colors = {"red", "green", "blue"}

for color in colors:

print(f"Color: {color}")

```

**Output (contoh):**

```

Color: blue
Color: green

Color: red

```

#### 2. Menggunakan Iterator Eksplisit

```python

numbers = {10, 20, 30}

iterator = iter(numbers)

print(next(iterator)) # 10

print(next(iterator)) # 20

print(next(iterator)) # 30

```

#### 3. Konversi ke List untuk Indeks

```python

fruits = {"apple", "banana", "cherry"}

fruit_list = list(fruits)

for i in range(len(fruit_list)):

print(f"Index {i}: {fruit_list[i]}")

```

**Output (contoh):**

```

Index 0: banana

Index 1: apple

Index 2: cherry

```

---
### **Operasi Selama Iterasi**

#### a. Transformasi Data

```python

s = {1, 2, 3}

squared = {x**2 for x in s} # Set comprehension: {1, 4, 9}

```

#### b. Filter Elemen

```python

numbers = {5, 12, 8, 15}

filtered = {x for x in numbers if x > 10} # {12, 15}

```

#### c. Agregasi Data

```python

total = 0

for num in {10, 20, 30}:

total += num

print(total) # 60

```

---

### **Peringatan Penting!**

1. **Jangan modifikasi set selama iterasi**

Perubahan ukuran set menyebabkan `RuntimeError`

```python

s = {1, 2, 3}

for x in s:
[Link](x*10) # RuntimeError: Set changed size during iteration

```

2. **Solusi untuk modifikasi**

Buat salinan terlebih dahulu:

```python

s = {1, 2, 3}

for x in [Link](): # Salinan set

[Link](x*10)

print(s) # {1, 2, 3, 10, 20, 30}

```

3. **Urutan tidak stabil** antar eksekusi:

```python

# Python <3.7: Urutan bisa berbeda tiap run

# Python ≥3.7: Urutan konsisten per sesi, tapi tidak terjamin

```

---

### **Perbandingan dengan Struktur Lain**

| Fitur | Set | List | Tuple |

|----------------|--------------------------|-------------------------|-------------------------|

| **Urutan** | ❌ Tidak terurut | ✅ Terurut | ✅ Terurut


|

| **Duplikat** | ❌ Tidak diizinkan | ✅ Diizinkan | ✅ Diizinkan


|

| **Performa** | ⚡ Cek keanggotaan O(1) | 🐢 Cek keanggotaan O(n) | 🐢


Cek keanggotaan O(n) |
| **Modifikasi** | ✅ Mutable | ✅ Mutable | ❌ Immutable
|

---

### **Aplikasi Praktis**

1. **Hapus duplikat saat iterasi**

```python

data = [1, 2, 2, 3, 4, 4, 4]

unique = set()

for num in data:

if num not in unique: # Cepat O(1)

print(num)

[Link](num)

```

2. **Cek kesamaan konten tanpa urutan**

```python

set1 = {"A", "B", "C"}

set2 = {"C", "B", "A"}

print(set1 == set2) # True (tidak peduli urutan)

```

3. **Cari elemen unik di beberapa set**

```python

backend = {"Python", "Java", "Go"}

frontend = {"JavaScript", "TypeScript", "Python"}

fullstack = backend & frontend # {"Python"}

```
---

### **Optimasi dengan Fungsi Bawaan**

#### a. `map()` untuk transformasi

```python

s = {1, 2, 3}

doubled = set(map(lambda x: x*2, s)) # {2, 4, 6}

```

#### b. `filter()` untuk seleksi

```python

s = {5, 12, 8, 15}

filtered = set(filter(lambda x: x > 10, s)) # {12, 15}

```

#### c. `any()`/`all()` untuk validasi

```python

grades = {85, 92, 78}

if any(grade >= 90 for grade in grades):

print("Ada nilai A")

```

---

### **Kapan Menggunakan Iterasi Set?**

1. Saat perlu **memproses elemen unik**

2. Untuk **operasi keanggotaan cepat** selama iterasi

3. Ketika **urutan tidak penting**


4. Pada **analisis himpunan** (gabungan, irisan, dll)

```python

# Contoh: Statistik kata unik

teks = "python adalah bahasa pemrograman python"

kata_unik = set([Link]())

print(f"Jumlah kata unik: {len(kata_unik)}") # 4

```

---

### **Kesimpulan**

Iterasi set digunakan untuk:

- Mengakses elemen unik tanpa urutan tertentu

- Memanfaatkan kecepatan cek keanggotaan O(1)

- Melakukan transformasi dan filter data

- Menangani operasi himpunan matematis

> **Catatan Penting**:

> "Meski urutan iterasi tidak tetap, Python 3.7+ menjamin konsistensi
urutan dalam satu sesi eksekusi program."

```python

# Analogi interaktif

kitchen_tools = {"pan", "spatula", "knife"}

for tool in kitchen_tools:

print(f"Using {tool}...")

# Output: Urutan acak, tapi semua alat terpakai!

```
- Keanggotaan (Membership)

### **Set Membership dalam Python**

**Set membership** adalah operasi untuk memeriksa apakah suatu


elemen merupakan anggota dari sebuah set. Python menyediakan
operator khusus dan metode bawaan untuk melakukan pengecekan
keanggotaan ini, yang merupakan salah satu operasi paling efisien pada
set karena menggunakan struktur data **hash table**.

---

### **Operator Membership Dasar**

| Operator | Contoh | Arti |

|----------|-------------------------|----------------------------------|

| **`in`** | `'apel' in buah_set` | `True` jika elemen ada dalam set |

| **`not in`** | `'naga' not in buah_set`| `True` jika elemen tidak ada |

**Contoh:**

```python

buah = {"apel", "mangga", "jeruk"}

print("apel" in buah) # Output: True

print("anggur" in buah) # Output: False

print("naga" not in buah) # Output: True

```

---
### **Mekanisme Kerja di Balik Layar**

Set menggunakan **hash table** untuk menyimpan elemen:

1. Python menghitung **hash value** dari elemen yang dicari

2. Langsung mengecek lokasi memori yang sesuai

3. Kompleksitas waktu: **O(1)** (konstan) untuk kasus rata-rata

```python

# Visualisasi hash table

Set: {apel, mangga, jeruk}

Hash apel → Lokasi memori 0x1234 → Ditemukan!

Hash anggur → Lokasi memori 0x5678 → Kosong ❌

```

---

### **Perbandingan dengan Struktur Data Lain**

| Operasi | Set/Dict | List/Tuple | String |

|------------------|----------|------------|----------|

| **Kompleksitas** | O(1) | O(n) | O(n) |

| **Contoh** | `x in s` | `x in lst` | `c in s` |

**Ilustrasi Perbedaan Performa:**

```python

# List besar (1 juta elemen)

list_besar = list(range(1000000))

%timeit 999999 in list_besar # ~5.8 ms (linear search)

# Set besar (1 juta elemen)

set_besar = set(list_besar)
%timeit 999999 in set_besar # ~0.0001 ms (hash lookup → 58,000x
lebih cepat!)

```

---

### **Aplikasi Praktis**

#### 1. Validasi Data Cepat

```python

valid_fruits = {"apel", "mangga", "jeruk", "anggur"}

user_input = input("Masukkan buah: ")

if user_input.lower() in valid_fruits:

print("Buah valid!")

else:

print("Buah tidak dikenal")

```

#### 2. Filter Duplikat

```python

data = [1, 2, 2, 3, 4, 4, 4, 5]

unik = []

terlihat = set()

for num in data:

if num not in terlihat: # Cepat O(1)

[Link](num)

[Link](num)

print(unik) # [1, 2, 3, 4, 5]
```

#### 3. Cek Irisan Himpunan

```python

admin = {"Alice", "Bob", "Charlie"}

online = {"Bob", "David", "Eve"}

# Cek apakah ada admin online

if admin & online: # Setara: [Link](online) == False

print("Ada admin online: ", admin & online)

```

---

### **Metode Bawaan Terkait Membership**

#### 1. `isdisjoint()`

Cek apakah dua set tidak memiliki irisan

```python

A = {1, 2}; B = {3, 4}

print([Link](B)) # True

```

#### 2. `issubset()` / `<=`

Cek apakah semua elemen ada di set lain

```python

C = {1, 2}; D = {1, 2, 3}

print(C <= D) # True

print([Link](D)) # True

```
#### 3. `issuperset()` / `>=`

Cek apakah mengandung semua elemen set lain

```python

print(D >= C) # True

print([Link](C)) # True

```

---

### **Peringatan Penting**

1. **Case Sensitivity**

```python

buah = {"apel", "Mangga"}

print("mangga" in buah) # False (huruf kapital penting)

```

2. **Tipe Data Harus Sama**

```python

nums = {1, 2, 3}

print("1" in nums) # False (string vs integer)

```

3. **Elemen Tidak Bisa Mutable**

```python

s = {1.2, ("tuple", "ok"), frozenset([1,2])}

# s = { [1,2] } # TypeError: unhashable type: 'list'

```
---

### **Optimasi untuk Data Besar**

Gantikan list dengan set saat melakukan frequent membership tests:

```python

# ❌ Tidak Efisien

data_list = [...] # 1 juta elemen

if item in data_list: # O(n) → lambat

...

# ✅ Solusi Efisien

data_set = set(data_list)

if item in data_set: # O(1) → cepat

...

```

---

### **Kesimpulan**

Set membership digunakan untuk:

- Memverifikasi keanggotaan elemen dengan cepat

- Validasi data input

- Implementasi filter duplikat

- Operasi himpunan (subset/irisan)

**Keunggulan Utama:**

```python

# Kecepatan hash table

apel in {juta_buah} # ⚡ 0.0001 ms vs 🐢 1000 ms pada list


```

> "When you need speed for membership tests, sets are your go-to
solution in Python."

> — Pythonic Wisdom

Dengan memanfaatkan set membership, Anda dapat mengoptimalkan


kode secara signifikan terutama saat bekerja dengan dataset besar! 🚀

- Tambah/Hapus Item

### **Menambah dan Menghapus Item Set dalam Python**

Set adalah struktur data **mutable** (dapat diubah) di Python. Berikut


operasi dasar untuk menambah dan menghapus elemen beserta contoh
penggunaannya:

---

### **1. Menambah Item**

#### a. `add()` - Tambah satu elemen

```python

buah = {"apel", "jeruk"}

[Link]("mangga")

print(buah) # {'apel', 'jeruk', 'mangga'}

[Link]("apel") # Duplikat diabaikan

print(buah) # Tidak berubah

```

#### b. `update()` - Tambah banyak elemen (dari iterable)


```python

buah = {"apel", "jeruk"}

[Link](["anggur", "kiwi"], {"nanas", "pisang"})

print(buah) # {'apel', 'jeruk', 'anggur', 'kiwi', 'nanas', 'pisang'}

```

---

### **2. Menghapus Item**

#### a. `remove()` - Hapus elemen spesifik (error jika tidak ada)

```python

buah = {"apel", "jeruk", "mangga"}

[Link]("jeruk")

print(buah) # {'apel', 'mangga'}

[Link]("durian") # KeyError: 'durian'

```

#### b. `discard()` - Hapus elemen spesifik (aman jika tidak ada)

```python

buah = {"apel", "mangga"}

[Link]("mangga") # {'apel'}

[Link]("durian") # Tidak error

```

#### c. `pop()` - Hapus dan kembalikan elemen acak

```python

angka = {10, 20, 30}

terhapus = [Link]()
print(f"Terhapus: {terhapus}, Sisa: {angka}")

# Output contoh: Terhapus: 10, Sisa: {20, 30}

```

#### d. `clear()` - Hapus semua elemen

```python

buah = {"apel", "jeruk"}

[Link]()

print(buah) # set()

```

---

### **Perbandingan Metode Penghapusan**

| Metode | Kelebihan | Kekurangan |

|--------------|------------------------------------|-----------------------------|

| **`remove()`**| Pastikan elemen ada | Error jika elemen tidak


ada |

| **`discard()`**| Aman untuk elemen tidak ada |- |

| **`pop()`** | Berguna saat perlu elemen acak | Tidak bisa pilih


elemen |

| **`clear()`** | Cepat hapus semua |- |

---

### **Operasi Lanjutan**

#### a. Hapus dengan kondisi

```python

angka = {1, 2, 3, 4, 5}

angka = {x for x in angka if x % 2 != 0} # Hapus genap


print(angka) # {1, 3, 5}

```

#### b. Hapus duplikat antar set

```python

set1 = {1, 2, 3}

set2 = {3, 4, 5}

set1 -= set2 # Hapus elemen set2 dari set1

print(set1) # {1, 2}

```

---

### **Peringatan Penting**

1. **Set tidak terurut**: `pop()` menghapus elemen acak

```python

for _ in range(3):

print({1, 2, 3}.pop(), end=" ") # Output: 1 2 3 (urutan acak)

```

2. **Jangan modifikasi set selama iterasi**

```python

s = {1, 2, 3}

for x in s:

[Link](x) # RuntimeError: Set changed size

```

3. **Solusi iterasi aman**

```python
s = {1, 2, 3}

for x in list(s): # Buat salinan

[Link](x)

print(s) # set()

```

---

### **Aplikasi Praktis**

1. **Manajemen keanggotaan grup**

```python

grup_a = {"Alice", "Bob"}

grup_a.add("Charlie")

grup_a.discard("Eve") # Aman jika tidak member

print("Anggota:", grup_a)

```

2. **Sistem cache unik**

```python

cache = set()

[Link]("data1")

[Link]("data2")

[Link]("data1") # Hapus jika tidak perlu

```

3. **Pemrosesan data streaming**

```python

terlihat = set()
data_stream = [1, 2, 2, 3, 3, 3]

for num in data_stream:

if num not in terlihat:

print(f"Data baru: {num}")

[Link](num)

```

---

### **Performa Operasi**

| Operasi | Kompleksitas | Contoh |

|------------|--------------|---------------------|

| **`add()`** | O(1) | `[Link](x)` |

| **`remove()`**| O(1) | `[Link](x)` |

| **`pop()`** | O(1) | `[Link]()` |

| **`in`** | O(1) | `x in s` |

```python

# Bukti kecepatan

import timeit

[Link]('[Link](100)', 's = set(range(10**6))', number=10000)

# ~0.001 detik untuk 10.000 operasi

```

---

### **Kesimpulan**

- **Penambahan Item**:
- Gunakan `add()` untuk satu elemen

- Gunakan `update()` untuk banyak elemen

- **Penghapusan Item**:

- `discard()` untuk penghapusan aman

- `remove()` untuk penghapusan dengan validasi

- `pop()` untuk penghapusan acak

- `clear()` untuk reset set

> **Catatan**: Selalu gunakan set ketika membutuhkan:

> - Operasi keanggotaan cepat (membership test)

> - Penghapusan duplikat otomatis

> - Operasi himpunan matematis

```python

# Analogi kehidupan nyata

tas_belanja = {"apel", "susu", "roti"}

tas_belanja.add("telur") # Tambah item

tas_belanja.discard("sabun") # Coba hapus yang tidak ada (aman)

tas_belanja.remove("roti") # Hapus item yang ada

print("Isi tas:", tas_belanja) # {'apel', 'susu', 'telur'}

```

- Salin Set (Copy)

### **Penyalinan (Copying) Set dalam Python**

Penyalinan set adalah proses membuat **duplikat independen** dari set


asli, sehingga modifikasi pada salinan tidak memengaruhi set asli (dan
sebaliknya). Karena set bersifat **mutable**, penyalinan yang benar
penting untuk menghindari perubahan tak terduga.
---

### **3 Metode Penyalinan Set**

#### 1. Shallow Copy dengan `copy()`

Membuat salinan baru yang independen, tetapi elemennya masih merujuk


objek yang sama.

```python

original = {"apel", "mangga", "jeruk"}

salinan = [Link]()

[Link]("anggur")

print(original) # {'apel', 'mangga', 'jeruk'} (tidak berubah)

print(salinan) # {'apel', 'mangga', 'jeruk', 'anggur'}

```

#### 2. Shallow Copy dengan Konstruktor `set()`

Membuat set baru dari set yang sudah ada.

```python

original = {1, 2, 3}

salinan = set(original)

[Link](2)

print(original) # {1, 2, 3} (tidak berubah)

print(salinan) # {1, 3}

```

#### 3. Assignment (`=`) ❌ BUKAN Salinan!

Hanya membuat referensi baru ke set yang sama:

```python
original = {"A", "B", "C"}

referensi = original # Bukan salinan!

[Link]("D")

print(original) # {'A', 'B', 'C', 'D'} (ikut berubah!)

```

---

### **Perbandingan Metode Penyalinan**

| Metode | Contoh | Independen? | Kelebihan |

|-----------------|-------------------------|-------------|-------------------------------|

| **`copy()`** | `salinan = [Link]()` | ✅ Ya | Ekspresif, mudah


dibaca |

| **`set()`** | `salinan = set(asli)` | ✅ Ya | Bisa digunakan untuk


iterable |

| **Assignment** | `salinan = asli` | ❌ Tidak | Hanya referensi


|

---

### **Deep Copy untuk Elemen Mutable**

Jika set berisi objek **mutable** (seperti list, set, dict), gunakan
`[Link]()`:

```python

import copy

original = {frozenset([1, 2]), [3, 4]} # Berisi mutable (list)

salinan = [Link](original)
[Link](5)

salinan_list = next(x for x in salinan if isinstance(x, list))

salinan_list.append(99)

print(original) # {frozenset({1, 2}), [3, 4]} (tidak berubah)

print(salinan) # {5, frozenset({1, 2}), [3, 4, 99]}

```

---

### **Mengapa Set Perlu Disalin?**

1. **Mempertahankan data asli**

Modifikasi pada salinan tidak mengubah set original.

2. **Eksperimen aman**

Uji coba operasi tanpa risiko merusak data sumber.

3. **Parallel processing**

Kirim salinan set ke thread/process berbeda.

---

### **Visualisasi Memori**

```

Original: 0x1234 ────> {"A", "B"}

Salinan: 0x5678 ────> {"A", "B"} # Objek berbeda

Referensi: 0x1234 ───> {"A", "B"} # Objek sama

```

---
### **Aplikasi Praktis**

#### 1. Backup data sementara

```python

konfigurasi = {"theme:dark", "lang:id", "notif:on"}

backup = [Link]()

[Link]("notif:on")

print("Backup aman:", backup) # Backup tetap lengkap

```

#### 2. Operasi set tanpa modifikasi original

```python

set_A = {1, 2, 3}

set_B = {3, 4, 5}

# Cek irisan tanpa mengubah set_A

irisan = set_A.copy()

irisan.intersection_update(set_B)

print(irisan) # {3}

```

#### 3. Multi-threading

```python

from threading import Thread

data_utama = {"task1", "task2", "task3"}

def proses_task(task_set):

task_set.add("task_done")
print("Proses:", task_set)

# Kirim salinan ke thread

Thread(target=proses_task, args=(data_utama.copy(),)).start()

```

---

### **Peringatan Penting**

1. **Shallow copy tidak menyalin objek mutable di dalam set**:

```python

original = {[1, 2], [3, 4]}

salinan = [Link]()

# Modifikasi elemen mutable memengaruhi original!

list_dalam_salinan = next(iter(salinan))

list_dalam_salinan.append(99)

print(original) # {[1, 2, 99], [3, 4]} ❌

```

2. **Set tidak bisa berisi mutable object langsung**:

```python

s = {[1, 2]} # TypeError: unhashable type: 'list'

```

3. **Solusi**: Gunakan `frozenset` atau `tuple` untuk elemen kompleks:

```python

aman = {frozenset([1, 2]), (3, 4)}

```
---

### **Kesimpulan**

- Gunakan **`copy()`** atau **`set()`** untuk shallow copy set

- Gunakan **`[Link]()`** jika set berisi objek mutable

- Hindari **assignment (`=`)** jika butuh salinan independen

> **Catatan Efisiensi**:

> Operasi salinan set memiliki kompleksitas **O(n)**, tetapi sangat


dioptimalkan di Python.

```python

# Best practice

data_asli = {"critical", "data"}

backup = data_asli.copy() # Backup aman

data_asli.add("new_item") # Modifikasi aman

print("Asli:", data_asli) # {'critical', 'data', 'new_item'}

print("Backup:", backup) # {'critical', 'data'}

```

- Operasi Set:

- Gabungan (Union)

Dalam Python, **union set** (gabungan himpunan) merujuk pada operasi


yang menggabungkan elemen-elemen dari dua set atau lebih,
menghasilkan **set baru** yang berisi semua elemen unik dari set-set
tersebut (duplikat dihilangkan secara otomatis).

### Cara Melakukan Union Set


Ada dua metode utama:

1. **Menggunakan method `union()`**

2. **Menggunakan operator `|`**

---

### Contoh Penggunaan

#### 1. Metode `union()`

```python

A = {1, 2, 3}

B = {3, 4, 5}

# Union A dan B

C = [Link](B)

print(C) # Output: {1, 2, 3, 4, 5}

# Union multiple set

D = {5, 6, 7}

E = [Link](B, D)

print(E) # Output: {1, 2, 3, 4, 5, 6, 7}

```

#### 2. Operator `|`

```python

A = {1, 2, 3}

B = {3, 4, 5}

C = A | B # Union A dan B

print(C) # Output: {1, 2, 3, 4, 5}


# Union multiple set

D = {5, 6, 7}

E=A|B|D

print(E) # Output: {1, 2, 3, 4, 5, 6, 7}

```

---

### Karakteristik Union Set

1. **Menghilangkan Duplikat**

Jika ada elemen yang sama di kedua set, hanya satu yang disimpan.

```python

{1, 2} | {2, 3} = {1, 2, 3} # Angka 2 tidak diduplikasi

```

2. **Tidak Memodifikasi Set Asli**

Operasi union menghasilkan set **baru**, set asli tetap utuh.

```python

A = {1, 2}

B = {3, 4}

C=A|B

print(A) # Output: {1, 2} (tidak berubah)

```

3. **Bisa Digabungkan dengan Tipe Lain**

`union()` bisa menerima list, tuple, dll. (asalkan iterable).

```python

A = {1, 2}
B = [2, 3, 4]

C = [Link](B) # Output: {1, 2, 3, 4}

```

---

### Perbedaan Metode `union()` vs Operator `|`

| Fitur | `union()` | Operator `|` |

|------------------------|-------------------------------|--------------------------|

| Jumlah argumen | Banyak (misal: `[Link](B, C, D)`) | Hanya dua


set (`A | B`) |

| Dukung tipe data lain | ✅ (list, tuple, dll) | ❌ (harus set semua) |

| Sintaks | `.union()` | Simbol pipe `|` |

---

### Contoh Praktis

```python

# Gabungkan set buah

buah_tropis = {"mangga", "pisang", "nanas"}

buah_dingin = {"apel", "anggur", "pisang"}

semua_buah = buah_tropis.union(buah_dingin)

# Output: {"mangga", "pisang", "nanas", "apel", "anggur"}

```

Union set sangat berguna untuk **konsolidasi data**, **filter nilai unik**,
atau **penggabungan basis data**.

- Irisan (Intersection)
### Irisan Set (Set Intersection) dalam Python

**Irisan set** (intersection) adalah operasi yang mengambil elemen-


elemen **yang sama (common)** dari dua set atau lebih. Hasilnya adalah
set baru berisi elemen yang ada di **semua set** yang dioperasikan.

### Cara Melakukan Irisan Set

1. **Menggunakan method `intersection()`**

2. **Menggunakan operator `&`**

---

### Contoh Penggunaan

#### 1. Metode `intersection()`

```python

A = {1, 2, 3, 4}

B = {3, 4, 5, 6}

# Irisan A dan B

C = [Link](B)

print(C) # Output: {3, 4} (elemen yang ada di A dan B)

# Irisan multiple set

D = {4, 5, 6}

E = [Link](B, D)

print(E) # Output: {4} (elemen yang ada di A, B, dan D)

```

#### 2. Operator `&`

```python

A = {1, 2, 3, 4}
B = {3, 4, 5, 6}

C = A & B # Irisan A dan B

print(C) # Output: {3, 4}

# Irisan multiple set

D = {4, 5, 6}

E=A&B&D

print(E) # Output: {4}

```

---

### Karakteristik Irisan Set

1. **Hanya Mengambil Elemen yang Sama**

Jika tidak ada elemen yang sama, hasilnya adalah **set kosong**
(`set()`).

```python

A = {1, 2}

B = {3, 4}

print(A & B) # Output: set()

```

2. **Tidak Memodifikasi Set Asli**

Operasi menghasilkan set **baru**, set asli tetap utuh.

```python

A = {1, 2, 3}

B = {2, 3, 4}

C = [Link](B)
print(A) # Output: {1, 2, 3} (tidak berubah)

```

3. **Bisa Digabungkan dengan Tipe Lain**

`intersection()` bisa menerima list, tuple, dll.

```python

A = {1, 2, 3}

B = [2, 3, 4]

C = [Link](B) # Output: {2, 3}

```

---

### Perbedaan Metode `intersection()` vs Operator `&`

| Fitur | `intersection()` | Operator `&` |

|------------------------|--------------------------------------|----------------------------|

| Jumlah argumen | Banyak (misal: `[Link](B, C)`) | Hanya


dua set (`A & B`) |

| Dukung tipe data lain | ✅ (list, tuple, dll) | ❌ (harus set semua)
|

| Sintaks | `.intersection()` | Simbol `&` |

---

### Contoh Praktis

```python

# Data pengguna yang online dan pengguna premium

pengguna_online = {"Alice", "Bob", "Charlie", "Diana"}

pengguna_premium = {"Bob", "Diana", "Eva", "Frank"}


# Pengguna online DAN premium

pengguna_online_premium =
pengguna_online.intersection(pengguna_premium)

print(pengguna_online_premium) # Output: {'Bob', 'Diana'}

```

### Manfaat Irisan Set

- Mencari kesamaan data (misal: produk yang tersedia di dua gudang).

- Filter kolaboratif (misal: user yang tergabung dalam dua grup sekaligus).

- Analisis data (misal: kata kunci yang muncul di semua dokumen).

> 💡 **Catatan:**

> Irisan set sangat efisien karena menggunakan properti **hash-table**


bawaan Python, sehingga operasi berjalan cepat bahkan untuk set besar.

- Selisih (Difference)

### Set Difference (Perbedaan Himpunan) dalam Python

**Set difference** (selisih himpunan) adalah operasi yang mengambil


elemen-elemen yang **hanya ada di set pertama**, tetapi **tidak ada di
set kedua** (atau set lainnya). Hasilnya adalah set baru berisi elemen
unik dari set pertama yang tidak dimiliki set kedua.

### Cara Melakukan Set Difference

1. **Menggunakan method `difference()`**

2. **Menggunakan operator `-`**

---

### Contoh Penggunaan

#### 1. Metode `difference()`

```python
A = {1, 2, 3, 4}

B = {3, 4, 5, 6}

# Elemen yang ada di A tapi TIDAK ada di B

C = [Link](B)

print(C) # Output: {1, 2}

# Elemen yang ada di B tapi TIDAK ada di A

D = [Link](A)

print(D) # Output: {5, 6}

# Difference dengan multiple set

E = {1, 4, 7}

F = [Link](B, E) # Elemen di A yang tidak ada di B dan tidak ada di


E

print(F) # Output: {2} (karena 1,3,4 ada di B/E)

```

#### 2. Operator `-`

```python

A = {1, 2, 3, 4}

B = {3, 4, 5, 6}

C = A - B # {1, 2}

D = B - A # {5, 6}

# Difference multiple set

E = {1, 4, 7}

F = A - B - E # A - B = {1,2}, lalu {1,2} - E = {2}


print(F) # Output: {2}

```

---

### Karakteristik Set Difference

1. **Tidak Komutatif**

`A - B` tidak sama dengan `B - A`.

```python

{1, 2} - {2, 3} = {1}

{2, 3} - {1, 2} = {3}

```

2. **Tidak Memodifikasi Set Asli**

Operasi menghasilkan set **baru**, set asli tetap utuh.

```python

A = {10, 20, 30}

B = {20, 40}

C=A-B

print(A) # Output: {10, 20, 30} (tidak berubah)

```

3. **Bisa Digabungkan dengan Tipe Lain**

`difference()` bisa menerima list, tuple, dll.

```python

A = {1, 2, 3}

B = [2, 3]

C = [Link](B) # Output: {1}

```
---

### Perbedaan Metode `difference()` vs Operator `-`

| Fitur | `difference()` | Operator `-` |

|------------------------|------------------------------------|----------------------------|

| Jumlah argumen | Banyak (misal: `[Link](B, C)`) | Hanya dua


set (`A - B`) |

| Dukung tipe data lain | ✅ (list, tuple, dll) | ❌ (harus set semua)
|

| Sintaks | `.difference()` | Simbol minus `-` |

---

### Contoh Praktis

```python

# Data produk

stok_gudang_A = {"laptop", "mouse", "keyboard", "monitor"}

stok_gudang_B = {"mouse", "monitor", "printer"}

# Produk yang HANYA ada di Gudang A

hanya_gudang_A = stok_gudang_A.difference(stok_gudang_B)

print(hanya_gudang_A) # Output: {'laptop', 'keyboard'}

# Produk yang HANYA ada di Gudang B

hanya_gudang_B = stok_gudang_B.difference(stok_gudang_A)

print(hanya_gudang_B) # Output: {'printer'}

```

### Manfaat Set Difference


- Mencari data unik di satu kelompok (misal: pelanggan yang belum
terdaftar promo).

- Analisis perbandingan (misal: fitur yang tersedia di versi software A tapi


tidak di B).

- Pembersihan data (misal: menghapus item yang sudah kadaluarsa dari


daftar stok).

> ⚠️**Perhatian:**

> Jika tidak ada elemen unik di set pertama, hasilnya adalah **set
kosong** (`set()`):

> ```python

> A = {10, 20}

> B = {10, 20}

> print(A - B) # Output: set()

> ```

- Selisih Simetris (Symmetric Difference)

### Symmetric Difference Set (Selisih Simetris) dalam Python

**Symmetric difference** (selisih simetris) adalah operasi yang


mengambil elemen-elemen yang **hanya ada di salah satu set**, tetapi
**tidak ada di kedua set** sekaligus. Hasilnya adalah **gabungan elemen
unik** dari kedua set, **dikurangi** elemen yang mereka punya bersama.

Secara matematis:

```

A ⊖ B = (A ∪ B) - (A ∩ B)

```

atau

```

A ⊖ B = (A - B) ∪ (B - A)

```
### Cara Melakukan Symmetric Difference

1. **Menggunakan method `symmetric_difference()`**

2. **Menggunakan operator `^`**

---

### Contoh Penggunaan

#### 1. Metode `symmetric_difference()`

```python

A = {1, 2, 3, 4}

B = {3, 4, 5, 6}

# Elemen yang hanya ada di A ATAU hanya ada di B (tidak di kedua set)

C = A.symmetric_difference(B)

print(C) # Output: {1, 2, 5, 6}

```

#### 2. Operator `^`

```python

A = {1, 2, 3, 4}

B = {3, 4, 5, 6}

C = A ^ B # Symmetric difference

print(C) # Output: {1, 2, 5, 6}

# Symmetric difference multiple set

D = {5, 6, 7}

E=A^B^D
print(E) # Output: {1, 2, 7}

```

---

### Karakteristik Symmetric Difference

1. **Komutatif**

`A ^ B` sama dengan `B ^ A`.

```python

{1, 2} ^ {2, 3} = {1, 3}

{2, 3} ^ {1, 2} = {3, 1} # Set tidak memperhatikan urutan

```

2. **Tidak Memodifikasi Set Asli**

Operasi menghasilkan set **baru**, set asli tetap utuh.

```python

X = {"a", "b"}

Y = {"b", "c"}

Z = X.symmetric_difference(Y)

print(X) # Output: {"a", "b"} (tidak berubah)

```

3. **Bisa Digunakan untuk Multiple Set**

Operator `^` mendukung operasi berantai:

```python

A ^ B ^ C ^ D # Elemen yang muncul ganjil kali

```

4. **Hanya Menerima Set untuk Operator `^`**


Method `symmetric_difference()` bisa menerima iterable (list, tuple),
tetapi operator `^` hanya untuk set.

```python

# Dengan method (bisa pakai list)

A = {1, 2, 3}

B = [2, 3, 4]

C = A.symmetric_difference(B) # Output: {1, 4}

# Dengan operator (error jika bukan set)

D = A ^ B # TypeError: unsupported operand type(s)

```

---

### Contoh Praktis

```python

# Data preferensi user

preferensi_user1 = {"action", "comedy", "sci-fi"}

preferensi_user2 = {"comedy", "drama", "romance"}

# Genre yang HANYA disukai salah satu user (tidak keduanya)

genre_unik = preferensi_user1.symmetric_difference(preferensi_user2)

print(genre_unik) # Output: {'action', 'sci-fi', 'drama', 'romance'}

```

### Manfaat Symmetric Difference

- **Mencari ketidakmiripan data**:

```python

file_server1 = {"[Link]", "[Link]", "[Link]"}


file_server2 = {"[Link]", "[Link]", "[Link]"}

# File yang tidak sinkron

file_tidak_sinkron = file_server1 ^ file_server2

print(file_tidak_sinkron) # Output: {'[Link]', '[Link]'}

```

- **Deteksi perubahan konfigurasi**:

```python

konfig_lama = {"port:80", "SSL:true", "timeout:30"}

konfig_baru = {"port:443", "SSL:true", "timeout:60"}

perubahan = konfig_lama ^ konfig_baru

print(perubahan) # Output: {'port:80', 'port:443', 'timeout:30',


'timeout:60'}

```

- **Validasi keunikan data**:

```python

data_sales_A = {"Alice", "Bob", "Charlie"}

data_sales_B = {"Bob", "Charlie", "Diana"}

# Sales yang hanya ada di satu tim

sales_spesial = data_sales_A ^ data_sales_B

print(sales_spesial) # Output: {'Alice', 'Diana'}

```

---
### Perbedaan dengan Operasi Set Lain

| Operasi | Simbol | Contoh A = {1,2,3}, B = {3,4,5} | Hasil |

|------------------|--------|----------------------------------|-------------|

| Union | `|` | `A | B` | {1,2,3,4,5}|

| Intersection | `&` | `A & B` | {3} |

| Difference | `-` | `A - B` | {1,2} |

| **Symmetric Diff** | `^` | `A ^ B` | **{1,2,4,5}** |

> 💡 **Fakta Unik:**

> Symmetric difference dari beberapa set adalah **elemen yang muncul
sebanyak bilangan ganjil** di semua set.

> ```python

> A = {1,2}, B = {2,3}, C = {3,4}

> print(A ^ B ^ C) # Output: {1,4}

> # 1 muncul 1x (ganjil), 4 muncul 1x (ganjil), 2 dan 3 muncul 2x (genap)

> ```

- Subset/Superset/Disjoint

### Subset, Superset, dan Disjoint Set dalam Python

Berikut penjelasan lengkap tentang tiga relasi himpunan penting dalam


Python:

---

### 1. **Subset (Himpunan Bagian)**

Himpunan A disebut **subset** dari B (`A ⊆ B`) jika **semua elemen A**
juga merupakan elemen B.

**Cara Mengecek:**

- Metode: `[Link](B)`
- Operator: `A <= B`

- **Subset Sejati** (A ⊂ B, A tidak sama dengan B): `A < B`

**Contoh:**

```python

A = {1, 2}

B = {1, 2, 3, 4}

print([Link](B)) # Output: True

print(A <= B) # Output: True

print(A < B) # Output: True (sejati karena A ≠ B)

C = {1, 2}

print(C <= B) # Output: True

print(C < B) # Output: False (karena C = B, bukan sejati)

```

---

### 2. **Superset (Himpunan Induk)**

Himpunan B disebut **superset** dari A (`B ⊇ A`) jika **B memuat semua
elemen A**.

**Cara Mengecek:**

- Metode: `[Link](A)`

- Operator: `B >= A`

- **Superset Sejati** (B ⊃ A, B tidak sama dengan A): `B > A`

**Contoh:**
```python

A = {1, 2}

B = {1, 2, 3, 4}

print([Link](A)) # Output: True

print(B >= A) # Output: True

print(B > A) # Output: True (sejati karena B ≠ A)

C = {1, 2, 3, 4}

print(C >= B) # Output: True

print(C > B) # Output: False (karena C = B)

```

---

### 3. **Disjoint Set (Himpunan Lepas)**

Dua himpunan A dan B disebut **disjoint** jika **tidak memiliki elemen


yang sama** (irisan kosong).

**Cara Mengecek:**

- Metode: `[Link](B)`

**Contoh:**

```python

X = {1, 2}

Y = {3, 4}

Z = {2, 5}

print([Link](Y)) # Output: True (tidak ada elemen sama)


print([Link](Z)) # Output: False (ada elemen 2 yang sama)

```

---

### Diagram Visualisasi

```

SUBSET/SUPERSET:

A = {1, 2} ───⊆───→ B = {1, 2, 3, 4}

B = {1, 2, 3, 4} ←───⊇─── A = {1, 2}

DISJOINT:

A = {🍎, 🍌} B = {🚗, 📱} → Tidak ada irisan

```

---

### Contoh Praktis

**Subset/Superset:**

```python

# Cek kategori produk

produk_diskon = {"laptop", "mouse"}

semua_produk = {"laptop", "keyboard", "mouse", "monitor"}

if produk_diskon.issubset(semua_produk):

print("Semua produk diskon tersedia di toko") # Output ini

```

**Disjoint:**
```python

# Alokasi sumber daya

server_A = {"CPU-1", "CPU-2", "RAM-1"}

server_B = {"CPU-3", "RAM-2"}

if server_A.isdisjoint(server_B):

print("Resource tidak bentrok") # Output ini

else:

print("Ada resource yang duplikat!")

```

---

### Tabel Perbandingan

| Relasi | Metode | Operator | Keterangan |

|----------------|----------------------|----------|-------------------------------------|

| **Subset** | `[Link](B)` | `A <= B` | True jika semua elemen A


ada di B |

| **Subset Sejati**| - | `A < B` | True jika A ⊆ B dan A ≠ B


|

| **Superset** | `[Link](A)` | `B >= A` | True jika B memuat


semua elemen A |

| **Superset Sejati**| - | `B > A` | True jika B ⊇ A dan B ≠ A


|

| **Disjoint** | `[Link](B)` |- | True jika A dan B tidak ada


elemen sama |

---

### Catatan Penting


1. **Set Kosong (`∅`)** selalu menjadi subset/superset:

```python

kosong = set()

S = {1, 2, 3}

print(kosong <= S) # True (subset)

print(kosong < S) # True (subset sejati)

print(S >= kosong) # True (superset)

```

2. **Kompatibilitas Tipe Data**:

Metode subset/superset/disjoint bisa menerima iterable (list, tuple):

```python

A = {1, 2, 3}

B = [3, 4, 5]

print([Link](B)) # False (karena 3 ada di kedua)

```

3. **Perbedaan Operator vs Metode**:

```python

# Operator subset (<=) vs proper subset (<)

C = {1, 2, 3}

D = {1, 2, 3}

print(C <= D) # True

print(C < D) # False (karena setara)

```

- **Dictionary**

- Pembuatan Dictionary

### Apa yang Dimaksud dengan Pembuatan Dictionary dalam Python?


**Dictionary** (disebut juga `dict`) dalam Python adalah struktur data
yang menyimpan kumpulan pasangan **kunci-nilai** (_key-value pairs_).
Setiap elemen dalam dictionary memiliki:

- **Kunci (key)**: Unik, tidak boleh duplikat, dan harus tipe data
_immutable_ (seperti string, angka, atau tuple).

- **Nilai (value)**: Dapat berisi tipe data apa pun (string, angka, list,
bahkan dictionary lain) dan boleh duplikat.

---

#### Cara Membuat Dictionary:

Berikut metode umum untuk membuat dictionary di Python:

1. **Menggunakan Kurung Kurawal `{}`**

Contoh:

```python

mahasiswa = {'nama': 'Budi', 'umur': 20, 'jurusan': 'Informatika'}

```

2. **Menggunakan Fungsi `dict()`**

Contoh:

```python

mahasiswa = dict(nama='Budi', umur=20, jurusan='Informatika')

```

3. **Dictionary Comprehension**

Contoh (membuat dictionary kuadrat):

```python

kuadrat = {x: x**2 for x in range(1, 6)}


# Hasil: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

```

4. **Menggabungkan Dua List dengan `zip()`**

Contoh:

```python

keys = ['nama', 'umur']

values = ['Dewi', 22]

data = dict(zip(keys, values))

# Hasil: {'nama': 'Dewi', 'umur': 22}

```

---

#### Karakteristik Penting Dictionary:

1. **Unordered** (sebelum Python 3.7): Urutan elemen tidak dijamin.

(Mulai Python 3.7+, dictionary **terurut** berdasarkan urutan


penyisipan.)

2. **Mutable**: Nilai bisa diubah setelah pembuatan.

3. **Dinamis**: Ukuran bisa berubah (bisa menambah/hapus elemen).

4. **Kunci Harus Unik**: Jika kunci duplikat, nilai terakhir yang akan
dipakai.

---

#### Contoh Operasi Dasar:

```python

# Membuat dictionary

buku = {'judul': 'Laskar Pelangi', 'penulis': 'Andrea Hirata', 'tahun': 2005}


# Mengakses nilai

print(buku['judul']) # Output: Laskar Pelangi

# Menambah elemen baru

buku['halaman'] = 529

# Mengubah nilai

buku['tahun'] = 2008

# Menghapus elemen

del buku['halaman']

```

---

#### Kegunaan Utama Dictionary:

- Menyimpan data terstruktur (contoh: data JSON).

- Pencarian data sangat cepat (kompleksitas O(1)) karena menggunakan


_hash table_.

- Merepresentasikan hubungan "pemetaan" (misal: kata-terjemahan, ID-


nama).

Dengan memahami dictionary, Anda bisa mengelola data secara fleksibel


dan efisien di Python! 🐍

- Akses Item

### **Akses Items Dictionary dalam Python**

Mengakses item (elemen) dalam dictionary Python berarti **mengambil


nilai (value)** berdasarkan **kunci (key)** yang spesifik atau mengambil
seluruh pasangan key-value. Berikut penjelasan lengkapnya:
---

#### **1. Cara Dasar Mengakses Nilai**

Gunakan **key** di dalam tanda kurung siku `[]`:

```python

mahasiswa = {'nama': 'Dewi', 'umur': 22, 'jurusan': 'Biologi'}

# Akses nilai dengan key 'nama'

print(mahasiswa['nama']) # Output: Dewi

```

⚠️**Peringatan**: Jika key tidak ada, akan muncul error `KeyError`.

Contoh: `print(mahasiswa['alamat'])` → Error!

---

#### **2. Menggunakan Method `get()`**

Aman untuk key yang mungkin tidak ada (mengembalikan `None` atau
nilai default):

```python

# Cek key 'alamat'

print([Link]('alamat')) # Output: None

# Dengan nilai default

print([Link]('alamat', 'N/A')) # Output: N/A

```

---
#### **3. Mengakses Semua Kunci (Keys)**

Gunakan method `.keys()`:

```python

kunci = [Link]()

print(kunci) # Output: dict_keys(['nama', 'umur', 'jurusan'])

```

---

#### **4. Mengakses Semua Nilai (Values)**

Gunakan method `.values()`:

```python

nilai = [Link]()

print(nilai) # Output: dict_values(['Dewi', 22, 'Biologi'])

```

---

#### **5. Mengakses Pasangan Key-Value**

Gunakan method `.items()` (sering dipakai dalam loop):

```python

for key, value in [Link]():

print(f"{key} : {value}")

# Output:

# nama : Dewi

# umur : 22

# jurusan : Biologi
```

---

#### **6. Mengecek Keberadaan Key**

Gunakan kata kunci `in`:

```python

if 'umur' in mahasiswa:

print("Key 'umur' tersedia") # Output ini akan muncul

```

---

#### **7. Contoh Operasi Akses Lainnya**

```python

# Ambil nilai sekaligus hapus item

umur = [Link]('umur')

print(umur) # Output: 22

# Ambil pasangan key-value terakhir (Python 3.7+)

last_item = [Link]()

print(last_item) # Output: ('jurusan', 'Biologi')

```

---

#### **Visualisasi Struktur Dictionary**

```python

mahasiswa = {
'nama': 'Dewi', # key: 'nama' → value: 'Dewi'

'umur': 22, # key: 'umur' → value: 22

'jurusan': 'Biologi' # key: 'jurusan' → value: 'Biologi'

```

---

#### **Kapan Menggunakan Akses Dictionary?**

- Saat perlu mengambil data berdasarkan identifikasi unik (contoh: cari


email user berdasarkan ID).

- Untuk iterasi data terstruktur (misal: memproses data JSON dari API).

- Ketika ingin memeriksa keberadaan data tertentu tanpa menyebabkan


error.

Dengan memahami cara akses yang tepat, Anda bisa bekerja lebih efisien
dengan dictionary di Python! 🚀

- Tambah/Hapus/Ubah Item

### **Tambah/Ubah/Hapus Item Dictionary dalam Python**

Operasi **tambah, ubah, dan hapus item** adalah fundamental dalam


mengelola data dictionary Python. Berikut penjelasan lengkap dengan
contoh praktis:

---

#### **1. Menambahkan Item Baru**

Gunakan **assignment operator (`=`) dengan key baru**:

```python

mahasiswa = {'nama': 'Rudi', 'jurusan': 'Fisika'}


mahasiswa['umur'] = 21 # Menambah key 'umur'

print(mahasiswa) # Output: {'nama': 'Rudi', 'jurusan': 'Fisika', 'umur': 21}

```

---

#### **2. Mengubah Nilai Item**

Assign **nilai baru ke key yang sudah ada**:

```python

mahasiswa['jurusan'] = 'Kimia' # Mengubah nilai 'jurusan'

print(mahasiswa) # Output: {'nama': 'Rudi', 'jurusan': 'Kimia', 'umur': 21}

```

---

#### **3. Menghapus Item**

Tiga metode utama:

- **`del` statement**

```python

del mahasiswa['umur'] # Hapus key 'umur'

print(mahasiswa) # Output: {'nama': 'Rudi', 'jurusan': 'Kimia'}

```

- **`.pop()`** (menghapus + mengembalikan nilai)

```python

jurusan = [Link]('jurusan')

print(jurusan) # Output: Kimia

print(mahasiswa) # Output: {'nama': 'Rudi'}

```

- **`.popitem()`** (menghapus item terakhir - Python 3.7+)


```python

last_item = [Link]()

print(last_item) # Output: ('nama', 'Rudi')

print(mahasiswa) # Output: {}

```

---

#### **4. Metode Khusus untuk Tambah/Ubah**

- **`.update()`** (menambah/menggabungkan dictionary):

```python

[Link]({'semester': 3, 'ipk': 3.75}) # Tambah multiple items

print(mahasiswa) # Output: {'semester': 3, 'ipk': 3.75}

```

- **Mengatur nilai default dengan `.setdefault()`**:

```python

[Link]('beasiswa', 'Tidak') # Tambah jika key tidak ada

print(mahasiswa['beasiswa']) # Output: Tidak

```

---

#### **5. Menghapus Semua Item**

Gunakan **`.clear()`** untuk reset dictionary:

```python

[Link]()

print(mahasiswa) # Output: {}

```
---

#### **6. Contoh Integrasi (Tambah/Ubah/Hapus dalam 1 Skenario)**

```python

inventory = {'apel': 10, 'pisang': 5}

# Tambah item baru

inventory['jeruk'] = 15

# Ubah nilai yang ada

inventory['apel'] = 8

# Hapus item

del inventory['pisang']

print(inventory) # Output: {'apel': 8, 'jeruk': 15}

```

---

#### **Peringatan Penting**

| Operasi | Risiko Error | Solusi Aman |

|------------------|---------------------------------------|---------------------------------|

| `dict[key] = val`| Key baru: tambah; Key ada: ubah |-


|

| `del dict[key]` | `KeyError` jika key tidak ada | Gunakan `if key in
dict` |

| `.pop(key)` | `KeyError` jika key tidak ada | Berikan argumen


kedua: default |
| `.update()` | Tidak ada error untuk key tidak ada | -
|

Contoh penanganan error:

```python

# Hapus dengan aman menggunakan pop()

jumlah = [Link]('mangga', 0) # Kembalikan 0 jika key tidak ada

print(jumlah) # Output: 0 (tanpa error)

```

---

#### **Diagram Alur Operasi**

```

[TAMBAH ITEM] ---> Gunakan: dict[kunci_baru] = nilai

[UBAH ITEM] ---> Gunakan: dict[kunci] = nilai_baru

[HAPUS ITEM] ---> Pilih:

├── del dict[kunci] (langsung hapus)

├── [Link](kunci) (ambil nilai lalu hapus)

└── [Link]() (hapus item terakhir)

```

Dengan menguasai operasi ini, Anda bisa memanipulasi data dictionary


secara dinamis dan efisien! 💻🔥

- Salin Dictionary

### **Salin (Copy) Dictionary dalam Python**


Membuat salinan dictionary berarti **menduplikasi isi dictionary ke objek
baru** sehingga Anda memiliki dua dictionary terpisah. Ini penting untuk
menghindari perubahan tak terduga pada data asli saat bekerja dengan
data duplikat.

---

#### **1. Masalah dengan Assignment Langsung (`=`)**

Jika Anda menggunakan `=`, Anda hanya membuat **referensi ke


dictionary yang sama** (bukan salinan independen):

```python

original = {'a': 1, 'b': 2}

salin = original # Ini bukan salinan, tapi referensi ke objek yang sama!

salin['a'] = 99

print(original) # Output: {'a': 99, 'b': 2} → Data asli ikut berubah!

```

---

#### **2. Metode Shallow Copy (Salinan Dangkal)**

Salinan baru dibuat, tetapi **objek di dalamnya tetap merujuk ke objek


asli**. Cocok untuk dictionary berisi tipe data *immutable* (seperti
integer, string).

- **Gunakan `.copy()`**:

```python

original = {'a': 1, 'b': 2}

salin = [Link]() # Membuat shallow copy


salin['a'] = 99

print(original) # Output: {'a': 1, 'b': 2} (tidak berubah)

```

- **Gunakan `dict(original)`**:

```python

salin = dict(original) # Cara alternatif shallow copy

```

##### **Peringatan untuk Nested Dictionary**:

Jika dictionary mengandung objek *mutable* (seperti list/dict lain), shallow


copy **tidak aman**:

```python

original = {'data': [1, 2, 3]}

salin = [Link]()

salin['data'].append(99)

print(original) # Output: {'data': [1, 2, 3, 99]} → Data asli ikut berubah!

```

---

#### **3. Metode Deep Copy (Salinan Mendalam)**

Solusi untuk dictionary bersarang (*nested*). Semua level diduplikasi


secara rekursif.

- **Gunakan `[Link]()`**:

```python

import copy

original = {'data': [1, 2, 3]}


salin = [Link](original) # Membuat salinan lengkap

salin['data'].append(99)

print(original) # Output: {'data': [1, 2, 3]} (tidak berubah)

print(salin) # Output: {'data': [1, 2, 3, 99]}

```

---

#### **4. Perbandingan Metode**

| Metode | Kelebihan | Kekurangan


| Cocok Untuk |

|-------------------------|---------------------------------------|-------------------------------------
|--------------------------|

| **Assignment (`=`)** | Cepat | Tidak membuat


salinan sebenarnya | Tidak direkomendasikan |

| **Shallow Copy** | Cepat, hemat memori | Tidak aman


untuk nested dictionary | Dictionary tanpa nested |

| **Deep Copy** | Aman untuk semua struktur | Lebih


lambat dan berat di memori | Nested dictionary |

---

#### **5. Contoh Praktis**

```python

# Shallow Copy untuk dictionary sederhana

menu = {'nasi goreng': 15000, 'es teh': 5000}

backup_menu = [Link]()

backup_menu['es teh'] = 6000 # Tidak pengaruhi menu asli

# Deep Copy untuk nested dictionary


restoran = {

'menu': {'makanan': ['sate', 'bakso'], 'minuman': ['jus']},

'karyawan': 10

backup_restoran = [Link](restoran)

backup_restoran['menu']['minuman'].append('soda') # Aman

```

---

#### **Kapan Menggunakan Shallow vs Deep Copy?**

- Gunakan **shallow copy** jika:

- Dictionary tidak mengandung objek mutable (seperti list/dict lain).

- Anda ingin perubahan pada objek *nested* tetap memengaruhi aslinya.

- Gunakan **deep copy** jika:

- Dictionary memiliki struktur bersarang kompleks.

- Anda ingin salinan sepenuhnya independen di semua level.

Dengan teknik salinan yang tepat, Anda bisa menghindari bug


tersembunyi saat memanipulasi data!

- Iterasi Dictionary

### **Iterasi Dictionary dalam Python**

Iterasi dictionary adalah proses **melakukan perulangan (looping) melalui


elemen-elemen dictionary** untuk mengakses kunci (keys), nilai (values),
atau pasangan key-value. Ini penting untuk memproses, memfilter, atau
memodifikasi data dalam dictionary secara efisien.

---
#### **1. Dasar Iterasi Dictionary**

Python menyediakan beberapa metode bawaan untuk iterasi:

- **Iterasi melalui keys** (default):

```python

mahasiswa = {'nama': 'Dira', 'umur': 20, 'jurusan': 'Matematika'}

for key in mahasiswa:

print(key)

# Output:

# nama

# umur

# jurusan

```

- **Iterasi melalui values**:

```python

for value in [Link]():

print(value)

# Output:

# Dira

# 20

# Matematika

```

- **Iterasi melalui key-value pairs** (paling umum):

```python

for key, value in [Link]():


print(f"{key} => {value}")

# Output:

# nama => Dira

# umur => 20

# jurusan => Matematika

```

---

#### **2. Teknik Iterasi Lanjutan**

- **Dengan conditional statement**:

```python

for key, value in [Link]():

if key == 'umur' and value > 18:

print("Mahasiswa dewasa")

```

- **Menggunakan `enumerate()`** (untuk mendapatkan indeks):

```python

for i, (key, value) in enumerate([Link](), 1):

print(f"Item {i}: {key}={value}")

# Output:

# Item 1: nama=Dira

# Item 2: umur=20

# Item 3: jurusan=Matematika

```

- **Dictionary Comprehension** (membuat dictionary baru):

```python
kuadrat = {k: v**2 for k, v in {'a': 2, 'b': 3, 'c': 4}.items()}

print(kuadrat) # Output: {'a': 4, 'b': 9, 'c': 16}

```

---

#### **3. Iterasi dengan Pengurutan (Sorting)**

- **Urutkan berdasarkan key**:

```python

for key in sorted([Link]()):

print(key, mahasiswa[key])

# Output:

# jurusan Matematika

# nama Dira

# umur 20

```

- **Urutkan berdasarkan value**:

```python

for key in sorted(mahasiswa, key=[Link]):

print(key, mahasiswa[key])

```

---

#### **4. Contoh Praktis: Pemrosesan Data**

```python

inventory = {'apel': 50, 'pisang': 120, 'jeruk': 85}


# Hitung total stok

total = 0

for jumlah in [Link]():

total += jumlah

print(f"Total stok: {total}") # Output: Total stok: 255

# Update stok (+10 untuk semua item)

for item in inventory:

inventory[item] += 10

print(inventory) # Output: {'apel': 60, 'pisang': 130, 'jeruk': 95}

```

---

#### **5. Peringatan Penting**

1. **Jangan modifikasi ukuran dictionary** selama iterasi:

```python

# ❌ Berbahaya!

for key in mahasiswa:

if key == 'umur':

del mahasiswa[key] # RuntimeError!

# ✅ Solusi: iterasi salinan keys

for key in list([Link]()):

if key == 'umur':

del mahasiswa[key]

```

2. **Hindari nested loops** untuk dictionary besar (kompleksitas O(n²)).


---

#### **Diagram Alur Iterasi**

```

START


[Ambil item] →───[Proses item] ───┐

│ │

▼ │

[Item berikutnya] ←───────────────┘


END

```

Dengan menguasai iterasi dictionary, Anda dapat:

- Memproses data JSON dari API

- Membuat laporan dari dataset

- Membangun pipeline transformasi data

- Menerapkan operasi batch pada konfigurasi

Iterasi adalah jantung dari manipulasi dictionary! 🔄🐍

- Keanggotaan (Membership)

### **Membership Dictionary dalam Python**


**Membership dictionary** adalah teknik untuk **memeriksa keberadaan
suatu kunci (key) atau nilai (value)** dalam dictionary. Ini dilakukan
menggunakan operator khusus untuk menentukan apakah elemen
tertentu ada di dalam struktur data dictionary.

---

#### **1. Operator Membership Utama**

- **`in`**: Memeriksa apakah **kunci** ada di dictionary

- **`not in`**: Memeriksa apakah **kunci** tidak ada di dictionary

```python

mahasiswa = {'nama': 'Dito', 'npm': '20123456', 'fakultas': 'Teknik'}

# Cek keberadaan KEY

print('npm' in mahasiswa) # Output: True

print('email' in mahasiswa) # Output: False

print('fakultas' not in mahasiswa) # Output: False

```

---

#### **2. Memeriksa Keberadaan Nilai (Value)**

Gunakan kombinasi dengan `.values()`:

```python

# Cek keberadaan VALUE

print('Dito' in [Link]()) # Output: True

print(20123456 in [Link]()) # Output: True (tipe data


diperhatikan)

print('teknik' in [Link]()) # Output: False (case-sensitive)


```

---

#### **3. Memeriksa Pasangan Key-Value**

Gunakan `.items()` untuk memeriksa pasangan lengkap:

```python

# Cek pasangan (key, value)

print(('nama', 'Dito') in [Link]()) # Output: True

print(('npm', 20123456) in [Link]()) # Output: True

print(('fakultas', 'Sains') in [Link]()) # Output: False

```

---

#### **4. Contoh Praktis Aplikasi**

```python

inventory = {'apel': 15, 'mangga': 8, 'jeruk': 22}

# Validasi stok sebelum transaksi

item = input("Item yang dibeli: ")

if item in inventory:

print(f"Stok tersedia: {inventory[item]} unit")

else:

print("Item tidak tersedia")

# Output jika input 'mangga': "Stok tersedia: 8 unit"

```
---

#### **5. Efisiensi Membership Check**

- **Pengecekan kunci** (`key in dict`) sangat efisien (O(1))

- **Pengecekan nilai** (`value in [Link]()`) kurang efisien (O(n))

- **Pengecekan pasangan** (`(key,value) in [Link]()`) efisien untuk


key yang ada

---

#### **6. Perbandingan dengan Tipe Data Lain**

| Operasi | List | Set | Dictionary |

|-----------------------|------|------|------------|

| `x in data` | O(n) | O(1) | **O(1)** |

| `x in [Link]()` | - |- | O(n) |

| `(k,v) in [Link]()`| - |- | O(1)* |

*Efisien ketika kunci sudah ada

---

#### **7. Tips Penting**

1. **Case Sensitivity**:

```python

data = {'Nama': 'Dito'}

print('nama' in data) # Output: False (huruf kapital berbeda)

```

2. **Pengecekan Tipe Data**:


```python

data = {'umur': '21'}

print(21 in [Link]()) # Output: False (string vs integer)

```

3. **Alternatif untuk Value Check**:

```python

# Lebih efisien untuk dictionary besar

exists = any(value == 21 for value in [Link]())

```

---

#### **Diagram Keputusan Membership**

```

Mulai


[Apakah key ada?] ──── Ya ───→ [Key ditemukan] ───→ Keluaran True

Tidak


[Apakah value perlu dicek?] ── Ya ─→ [Iterasi values] ── Ditemukan ─→
True

│ │

Tidak Tidak

│ │

▼ ▼
Keluaran False Keluaran False

```

Membership test adalah operasi fundamental untuk:

- Validasi data sebelum pemrosesan

- Pencegahan error (misal: `KeyError`)

- Filtering data

- Pengambilan keputusan dalam program

Dengan memahami konsep ini, Anda bisa menulis kode yang lebih aman
dan efisien! 🔍🐍

- Pemeriksaan `all()`/`any()`

### **Pemeriksaan `all()` dan `any()` pada Dictionary di Python**

Fungsi `all()` dan `any()` digunakan untuk melakukan **pemeriksaan logis


pada elemen-elemen dictionary**. Berikut penjelasan lengkapnya:

---

#### **1. `all(dictionary)`**

Mengembalikan `True` hanya jika **semua kunci (keys)** dalam dictionary


bernilai `True` (atau dictionary kosong).

```python

# Contoh 1: Semua kunci truthy

dict1 = {1: "a", "b": False, 2.5: []}

print(all(dict1)) # Output: True (karena semua key ≠ 0/None/False)

# Contoh 2: Ada kunci falsy (0)

dict2 = {0: "nol", 1: "satu"}


print(all(dict2)) # Output: False (karena ada key 0)

```

---

#### **2. `any(dictionary)`**

Mengembalikan `True` jika **minimal satu kunci** dalam dictionary


bernilai `True`.

```python

# Contoh 1: Ada minimal satu truthy key

dict3 = {0: False, None: 0, "key": True}

print(any(dict3)) # Output: True (karena "key" truthy)

# Contoh 2: Semua kunci falsy

dict4 = {0: "a", False: "b", None: "c"}

print(any(dict4)) # Output: False

```

---

#### **3. Pemeriksaan Values atau Items**

Untuk memeriksa **nilai (values)** atau **pasangan lengkap**, gunakan


kombinasi dengan:

- `.values()` untuk nilai

- `.items()` untuk pasangan key-value

```python

data = {"a": 10, "b": 0, "c": 30}

# Cek semua values > 0?


print(all(x > 0 for x in [Link]())) # Output: False (karena b=0)

# Cek apakah ada value genap?

print(any(x % 2 == 0 for x in [Link]())) # Output: True (a=10 genap)

# Cek apakah semua key berupa string dan value integer?

print(all(isinstance(k, str) and isinstance(v, int) for k, v in [Link]()))

# Output: True

```

---

#### **4. Contoh Praktis**

**Validasi konfigurasi sistem**:

```python

config = {"auto_update": True, "backup_enabled": False, "log_level":


"debug"}

# Apakah semua fitur boolean sudah dikonfigurasi?

settings_configured = all(type(v) is bool for v in [Link]()

if k in ["auto_update", "backup_enabled"])

print(settings_configured) # Output: True

# Apakah ada fitur yang diaktifkan?

any_active = any(v is True for v in [Link]()

if k in ["auto_update", "backup_enabled"])

print(any_active) # Output: True (karena auto_update=True)

```
---

#### **5. Perilaku Khusus**

| Scenario | `all()` | `any()` | Penjelasan |

|------------------------|---------|---------|-------------------------------------|

| Dictionary kosong `{}` | `True` | `False` | `all()` true untuk iterable


kosong |

| Key `False` | `False` | `False` | Key falsy |

| Key `0` | `False` | `False` | Key falsy |

| Key `""` (string kosong)| `False` | `False` | Key falsy |

| Key `None` | `False` | `False` | Key falsy |

| Key `[]` (list kosong) | `True` | `True` | **Perhatian!** Container kosong


≠ falsy sebagai key |

---

#### **6. Visualisasi Logika**

**`all()`**:

```

[✔️] [✔️] [✔️] → True

[✔️] [❌] [✔️] → False

[] (kosong) → True

```

**`any()`**:

```

[❌] [❌] [✔️] → True

[❌] [❌] [❌] → False

[] (kosong) → False

```
---

#### **7. Tips Penting**

1. **Hanya periksa keys secara default**

```python

data = {0: "truthy value"}

print(any(data)) # Output: False (karena key=0 falsy)

```

2. **Gunakan generator expression** untuk efisiensi memori:

```python

# Lebih efisien daripada list comprehension

any(x > 100 for x in large_dict.values())

```

3. **Kombinasi dengan fungsi lain** untuk logika kompleks:

```python

# Cek apakah semua nilai numerik > 10

all(v > 10 for k, v in [Link]() if isinstance(v, (int, float)))

```

---

### **Kapan Digunakan?**

- `all()`: Validasi persyaratan wajib (misal: semua field form terisi)

- `any()`: Deteksi keberadaan kondisi (misal: apakah ada error dalam log)
Dengan memahami `all()` dan `any()`, Anda bisa menulis kode validasi
yang lebih ringkas dan ekspresif! 🔍✅

- Dictionary Comprehension

### **Dictionary Comprehension dalam Python**

**Dictionary comprehension** adalah teknik singkat dan elegan untuk


**membuat dictionary baru** dari iterable (seperti list, tuple, atau range)
dengan sintaks satu baris. Mirip dengan list comprehension, tetapi
menghasilkan struktur dictionary dengan format `{key: value}`.

---

#### **1. Sintaks Dasar**

```python

{key_expression: value_expression for item in iterable}

```

Contoh sederhana:

```python

# Kuadrat bilangan dari 1-5

kuadrat = {x: x**2 for x in range(1, 6)}

print(kuadrat) # Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

```

---

#### **2. Tambahkan Kondisi (`if`)**

Filter elemen sebelum dimasukkan ke dictionary:

```python
# Hanya bilangan genap

genap_kuadrat = {x: x**2 for x in range(10) if x % 2 == 0}

print(genap_kuadrat) # Output: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

```

---

#### **3. Transformasi Key/Value**

Lakukan operasi pada key dan value:

```python

kata = ["apple", "banana", "cherry"]

panjang = {[Link](): len(k) for k in kata}

print(panjang) # Output: {'APPLE': 5, 'BANANA': 6, 'CHERRY': 6}

```

---

#### **4. Pengolahan Dictionary Exist**

Transformasi dictionary lain:

```python

harga = {'apel': 10000, 'jeruk': 8000, 'mangga': 12000}

diskon = {buah: harga * 0.9 for buah, harga in [Link]()} # Diskon


10%

print(diskon) # Output: {'apel': 9000.0, 'jeruk': 7200.0, 'mangga':


10800.0}

```

---

#### **5. Kondisi Kompleks (`if-else`)**


```python

# Beri label "mahal" jika harga > 10000, "murah" jika tidak

kategori = {buah: "mahal" if harga > 10000 else "murah"

for buah, harga in [Link]()}

print(kategori) # Output: {'apel': 'murah', 'jeruk': 'murah', 'mangga':


'mahal'}

```

---

#### **6. Nested Dictionary Comprehension**

Membuat struktur bersarang:

```python

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat_dict = {(i, j): matrix[i][j] for i in range(3) for j in range(3)}

print(flat_dict)

# Output: {(0,0):1, (0,1):2, (0,2):3, (1,0):4, ...}

```

---

#### **7. Perbandingan dengan Loop Tradisional**

**Tanpa comprehension** (lebih panjang):

```python

kuadrat = {}

for x in range(1, 6):

kuadrat[x] = x**2

```
**Dengan comprehension** (ringkas dan Pythonic):

```python

kuadrat = {x: x**2 for x in range(1, 6)}

```

---

#### **8. Batasan Penggunaan**

- **Hindari untuk logika kompleks** (gunakan loop biasa jika perlu banyak
kondisi).

- **Tidak disarankan untuk efek samping** (seperti mengubah variabel


global).

- **Prioritaskan keterbacaan** – jangan paksa jadi satu baris jika


mengurangi kejelasan.

---

### **Kapan Menggunakan Dictionary Comprehension?**

| Scenario | Contoh Penggunaan |

|-----------------------------------|------------------------------------|

| Transformasi data | Konversi satuan, normalisasi teks |

| Filtering data | Ambil item yang memenuhi syarat |

| Pembuatan kamus cepat | Lookup table, konfigurasi default |

| Pemrosesan data fungsional | Operasi map/filter tanpa lambda |

---

### **Contoh Praktis Dunia Nyata**

1. **Hit frekuensi karakter dalam string**:

```python
teks = "hello world"

frekuensi = {char: [Link](char) for char in set(teks)}

print(frekuensi) # Output: {'h':1, 'e':1, 'l':3, ...}

```

2. **Konversi suhu daftar kota**:

```python

suhu_c = {'Jakarta': 32, 'Tokyo': 15, 'Berlin': 8}

suhu_f = {kota: (c * 9/5) + 32 for kota, c in suhu_c.items()}

```

3. **Normalisasi data produk**:

```python

produk = [("Laptop", 12000000), ("Mouse", 150000)]

produk_dict = {[Link](): harga for nama, harga in produk}

```

---

#### **Visualisasi Alur Kerja**

```

[Iterable]


[Item] → [Kondisi?] ── Tidak ─┐

│ │ │

Ya Ya │

│ ▼ │

│ [Transform Key] │
▼ │ │

[Transform Value]◄────────────┘


{Key: Value} → Dictionary Baru

```

Dictionary comprehension menghemat 30-50% kode dan meningkatkan


keterbacaan! 🚀🐍

- Frekuensi Kata (*Contoh Aplikasi*)

### **Frekuensi Kata dengan Dictionary Python**

**Frekuensi kata** adalah contoh aplikasi praktis dictionary Python untuk


**menghitung kemunculan setiap kata dalam teks**. Ini adalah teknik
fundamental dalam pemrosesan bahasa alami (*NLP*) dan analisis teks.

---

#### **Alur Kerja Frekuensi Kata**

```mermaid

flowchart TD

A[Input Teks] --> B[Pembersihan Teks]

B --> C[Tokenisasi Kata]

C --> D[Inisialisasi Dictionary]

D --> E[Loop Kata]

E --> F{Kata ada di dict?}

F -->|Ya| G[Tambah Counter]

F -->|Tidak| H[Tambah Entry Baru]

G & H --> I[Output Frekuensi]


```

---

#### **Implementasi Langkah Demi Langkah**

1. **Pembersihan Teks**

Hilangkan karakter non-alfanumerik dan ubah ke huruf kecil:

```python

import re

teks = "Halo! Dunia Python. Python itu keren, dunia Python


menyenangkan."

teks_bersih = [Link](r'[^\w\s]', '', teks).lower()

# Output: "halo dunia python python itu keren dunia python


menyenangkan"

```

2. **Tokenisasi** (memecah teks menjadi kata-kata):

```python

kata_kata = teks_bersih.split()

# Output: ['halo', 'dunia', 'python', 'python', ...]

```

3. **Hitung Frekuensi dengan Dictionary**:

```python

frekuensi = {}

for kata in kata_kata:

frekuensi[kata] = [Link](kata, 0) + 1

```
4. **Output** (urutkan berdasarkan frekuensi tertinggi):

```python

for kata, count in sorted([Link](), key=lambda x: x[1],


reverse=True):

print(f"{kata}: {count}")

# Output:

# python: 3

# dunia: 2

# halo: 1

# itu: 1

# keren: 1

# menyenangkan: 1

```

---

#### **Versi Lanjutan dengan `Counter`**

Python menyediakan tools khusus untuk membuat lebih efisien:

```python

from collections import Counter

kata_kata = teks_bersih.split()

frekuensi = Counter(kata_kata)

print(frekuensi.most_common(3))

# Output: [('python', 3), ('dunia', 2), ('halo', 1)]

```
---

#### **Aplikasi Dunia Nyata**

1. **Analisis Sentimen**

Identifikasi kata kunci positif/negatif:

```python

kata_positif = {'senang', 'bagus', 'menyenangkan'}

for kata, count in [Link]():

if kata in kata_positif:

print(f"Kata positif ditemukan: {kata} ({count}x)")

```

2. **Deteksi Topik**

Hitung kata kunci spesifik:

```python

topik_tech = [Link]('python', 0) + [Link]('programming',


0)

```

3. **Pembersihan Stop Words**

Abaikan kata umum seperti "dan", "di", "yang":

```python

stop_words = {'itu', 'dan', 'di', 'yang'}

frekuensi_bersih = {k: v for k, v in [Link]() if k not in


stop_words}

```

---
#### **Visualisasi Hasil**

Kata | Frekuensi | Visual

-----|-----------|--------

`python` | 3 | ███████

`dunia` | 2 | ████

`halo` | 1 | ██

`keren` | 1 | ██

---

#### **Optimasi untuk Teks Besar**

- Gunakan generator untuk hemat memori:

```python

with open('buku_besar.txt', 'r') as file:

frekuensi = Counter(kata for baris in file

for kata in [Link](r'[^\w\s]', '', baris).lower().split())

```

- Multiproses untuk dataset sangat besar

---

### **Mengapa Dictionary Cocok untuk Frekuensi Kata?**

1. **Pencarian O(1)** - Cepat bahkan untuk jutaan kata

2. **Update Efisien** - Operasi `frekuensi[kata] += 1` sangat optimal

3. **Fleksibel** - Mudah ditambah dengan logika tambahan (filter,


transformasi)

Contoh ini menunjukkan kekuatan dictionary sebagai struktur data untuk


pemrosesan data nyata! 📊🐍
####*** K O M P L E K S I T A S A L G O R I T M A***

### **Kompleksitas Algoritma dalam Python: O(1), O(n), O(n²)**

Kompleksitas algoritma mengukur **seberapa efisien waktu eksekusi atau


penggunaan memori** suatu operasi meningkat seiring pertumbuhan
ukuran input (dilambangkan dengan `n`). Berikut penjelasan untuk tiga
kompleksitas umum:

---

#### **1. O(1) - Constant Time (Waktu Konstan)**

- **Artinya**: Waktu eksekusi **tidak tergantung ukuran input**

- **Contoh Python**:

```python

# Akses elemen dictionary

data_dict = {'a': 1, 'b': 2, 'c': 3}

nilai = data_dict['b'] # O(1)

# Operasi aritmetika dasar

x = 10 + 5 # O(1)

```

- **Visualisasi**:

```

n=1 → waktu = 1 unit

n=1000 → waktu = 1 unit

```

---
#### **2. O(n) - Linear Time (Waktu Linear)**

- **Artinya**: Waktu eksekusi **berbanding lurus dengan ukuran input**

- **Contoh Python**:

```python

# Loop melalui list

numbers = [1, 2, 3, ..., n] # n elemen

for num in numbers: # O(n)

print(num)

# Pencarian linear

if "target" in some_list: # O(n)

```

- **Visualisasi**:

```

n=1 → waktu = 1 unit

n=1000 → waktu = 1000 unit

```

---

#### **3. O(n²) - Quadratic Time (Waktu Kuadrat)**

- **Artinya**: Waktu eksekusi **berbanding dengan kuadrat ukuran


input**

- **Contoh Python**:

```python

# Nested loop

for i in range(n): # O(n²)

for j in range(n):
print(i, j)

# Bubble sort (worst case)

[3, 2, 1] → [2, 3, 1] → [2, 1, 3] → [1, 2, 3] # O(n²)

```

- **Visualisasi**:

```

n=1 → waktu = 1 unit

n=1000 → waktu = 1,000,000 unit

```

---

#### **Perbandingan Grafik Pertumbuhan**

```

Waktu

| O(n²)

| /

| /

| /

| /

| /

| /

| / O(n)

| / /

| / /

| / /
| / /

|___________/___/_________ O(1)

Ukuran Input (n)

```

---

#### **Contoh Nyata dalam Struktur Data Python**

| Operasi | Dictionary (Hash Table) | List (Array) | Keterangan


|

|-----------------------|-------------------------|--------------|--------------------------|

| Akses Elemen | **O(1)** | O(1) | Indeks langsung


|

| Pencarian | **O(1)** | O(n) | Cek keberadaan nilai


|

| Penyisipan | **O(1)** | O(n) | List butuh geser


elemen |

| Nested Loop |- | **O(n²)** | Hindari jika mungkin


|

---

#### **Mengapa Pemahaman Kompleksitas Penting?**

1. **Optimasi Kode**:

```python

# O(n) lebih baik dari O(n²)

# Buruk: O(n²)

for i in range(n):

if i in some_list: # Pencarian O(n) dalam loop O(n)


# Lebih baik: O(n)

some_set = set(some_list) # Konversi ke set O(n)

for i in range(n): # Pengecekan O(1)

if i in some_set:

```

2. **Prediksi Performa**:

- Input 1000 elemen:

O(1) → 1 ms

O(n) → 1000 ms

O(n²) → 1,000,000 ms ≈ 16 menit!

3. **Skalabilitas**:

Algoritma O(n²) akan lambat untuk dataset besar.

---

#### **Aturan Praktis Pemilihan Struktur Data**

| Skenario | Rekomendasi | Kompleksitas |

|---------------------------|---------------------|--------------|

| Sering akses by key | Dictionary | O(1) |

| Koleksi data berurutan | List | O(1) indeks |

| Cek keanggotaan | Set (bukan List) | O(1) |

| Operasi matematika himpunan| Set | O(1)-O(n) |

Dengan memahami kompleksitas algoritma, Anda bisa menulis kode


Python yang lebih efisien dan siap menghadapi data berskala besar! 🚀🐍

### **Kompleksitas O(nᵏ) dalam Python: Polynomial Time**


**Ya**, kompleksitas O(nᵏ) (disebut **polynomial time**) memang ada
dalam Python, terutama pada algoritma-algoritma yang melibatkan
nested loop atau operasi kombinatorial. Berikut penjelasan lengkapnya:

---

#### **1. Apa itu O(nᵏ)?**

Kompleksitas di mana waktu eksekusi **berbanding lurus dengan n


pangkat k**, di mana:

- `n` = ukuran input

- `k` = konstanta eksponen (k > 2)

```

Contoh:

O(n³) → n=10 → 10³ = 1000 operasi

O(n⁴) → n=10 → 10⁴ = 10000 operasi

```

---

#### **2. Contoh Implementasi di Python**

**a. O(n³) - Cubic Time (3 nested loops):**

```python

# Contoh: Perkalian matriks 3x3

def multiply_matrices(A, B):

n = len(A)

result = [[0] * n for _ in range(n)]

for i in range(n): # O(n)


for j in range(n): # O(n)

for k in range(n): # O(n)

result[i][j] += A[i][k] * B[k][j] # Total: O(n³)

return result

```

**b. O(n⁴) - Quartic Time (4 nested loops):**

```python

# Contoh: Pencarian semua kombinasi 4 elemen

def find_combinations(data):

n = len(data)

for i in range(n): # O(n)

for j in range(i+1, n): # O(n)

for k in range(j+1, n): # O(n)

for m in range(k+1, n): # O(n)

print(data[i], data[j], data[k], data[m]) # O(n⁴)

```

---

#### **3. Karakteristik Utama**

| Eksponen (k) | Nama Kompleksitas | Contoh Algoritma |

|--------------|-------------------|-----------------------------------|

| k=3 | **Cubic Time** | Perkalian matriks naif, Floyd-Warshall |

| k=4 | **Quartic Time** | Brute-force 4D grid search |

| k=5 | **Quintic Time** | Algoritma enumerasi kompleks |

---
#### **4. Visualisasi Pertumbuhan**

```

n | O(n³) | O(n⁴) | O(n⁵)

-------------------------------

1 |1 |1 |1

2 |8 | 16 | 32

5 | 125 | 625 | 3125

10 | 1,000 | 10,000 | 100,000

100| 1e6 | 1e8 | 1e10

```

---

#### **5. Kapan Terjadi di Python?**

Kompleksitas ini muncul saat:

- Memproses struktur data multidimensi (matriks, tensor)

- Algoritma brute-force untuk optimasi kombinatorial

- Operasi deep nested loops

- Pemrosesan graf padat (complete graphs)

- Simulasi fisika 3D/4D

**Contoh nyata:**

```python

# Analisis sentimen 3 dimensi: [dokumen, kata, karakter]

for doc in corpus: # O(d)

for word in [Link](): # O(w)

for char in word: # O(c)

process(char) # Total: O(d·w·c) ≈ O(n³)

```
---

#### **6. Bahaya O(nᵏ) untuk k Besar**

Untuk `k ≥ 3`:

- **Skalabilitas buruk**: Input 10× lebih besar → Waktu 1000× lebih lama

- **Tidak feasible untuk n besar**:

```python

n=100, k=4 → 100.000.000 operasi (masih bisa dijalankan)

n=1000, k=4 → [Link].000 operasi (≈11.5 hari di CPU 1 GHz)

```

---

#### **7. Strategi Mengatasi O(nᵏ)**

1. **Optimasi Algoritma**:

```python

# Ganti O(n³) perkalian matriks dengan Strassen Algorithm (O(n²·⁸¹))

from [Link] import multi_dot

result = multi_dot([A, B, C]) # Dioptimalkan

```

2. **Dynamic Programming**:

```python

# Contoh: Floyd-Warshall O(n³) → Tidak bisa di bawah O(n³) tapi bisa


dioptimasi

```

3. **Parallel Processing**:
```python

from joblib import Parallel, delayed

results = Parallel(n_jobs=-1)(delayed(process)(i,j,k)

for i in range(n) for j in range(n) for k in range(n))

```

4. **Hindari Brute-Force**:

Gunakan algoritma greedy atau divide-and-conquer

---

#### **Perbandingan dengan Kompleksitas Lain**

```mermaid

flowchart LR

A[O(1)] -->|Terbaik| B[O(log n)]

B --> C[O(n)]

C --> D[O(n log n)]

D --> E[O(n²)]

E --> F[O(nᵏ) k≥3]

F --> G[O(2ⁿ)] -->|Terburuk| H[O(n!)]

```

---

### **Kesimpulan**

Kompleksitas O(nᵏ) memang ada di Python dan digunakan dalam berbagai


algoritma polynomial-time. Meskipun lebih baik daripada eksponensial
(O(2ⁿ)), kompleksitas ini menjadi **tidak praktis untuk n besar dan k ≥
3**.
Kunci penanganannya:

- Gunakan library optimasi (NumPy, SciPy)

- Terapkan algoritma lebih efisien

- Manfaatkan paralelisasi

- Hindari nested loop dalam kode jika memungkinkan

Dengan memahami karakteristik ini, Anda bisa mendesain solusi yang


lebih skalabel! 🚀

-----------------------------------------------------------------------

#### **4. Operator**

- **Aritmetika (Arithmetic)**

### **Operator Aritmatika dalam Python**

Operator aritmatika adalah simbol khusus yang digunakan untuk


**melakukan operasi matematika dasar** pada nilai numerik (integer,
float, complex). Berikut penjelasan lengkapnya:

---

#### **Daftar Operator Aritmatika Dasar**

| Operator | Nama | Contoh | Hasil (dari `a = 10`, `b = 3`) |

|----------|---------------|-------------|--------------------------------|

| `+` | Penjumlahan | `a + b` | `13` |

| `-` | Pengurangan | `a - b` | `7` |

| `*` | Perkalian | `a * b` | `30` |

| `/` | Pembagian | `a / b` | `3.333...` (float) |

| `//` | **Floor Division** | `a // b` | `3` (integer) |

| `%` | **Modulus** (Sisa Bagi) | `a % b` | `1` (sisa 10÷3) |


| `**` | **Eksponen** (Pangkat) | `a ** b` | `1000` (10³) |

---

#### **1. Contoh Implementasi**

```python

# Operasi dasar

x = 15

y=4

print("Penjumlahan:", x + y) # 19

print("Pengurangan:", x - y) # 11

print("Perkalian:", x * y) # 60

print("Pembagian:", x / y) # 3.75

print("Floor Division:", x // y) # 3 (pembulatan ke bawah)

print("Modulus:", x % y) # 3 (sisa 15÷4 = 3*4 + 3)

print("Pangkat:", x ** y) # 50625 (15⁴)

```

---

#### **2. Operator Gabungan (Augmented Assignment)**

Untuk mempersingkat operasi:

```python

a=5

a += 3 # Sama dengan a = a + 3 → 8

a *= 2 # a = 8 * 2 → 16

a **= 2 # a = 16² → 256

print(a) # Output: 256


```

---

#### **3. Prioritas Operator (Operator Precedence)**

Urutan eksekusi operasi (mirip matematika):

1. `()` (Kurung)

2. `**` (Eksponen)

3. `*`, `/`, `//`, `%`

4. `+`, `-`

```python

hasil = 10 + 3 * 2 ** 2 # 3*(2²)=12 → 10+12=22

print(hasil) # Output: 22

# Gunakan kurung untuk mengubah urutan

hasil = (10 + 3) * 2 ** 2 # 13*4=52

```

---

#### **4. Operasi pada Tipe Data Berbeda**

- **Integer vs Float**: Hasil float

```python

print(5 + 2.5) # 7.5 (float)

```

- **Complex Numbers**:

```python

c = 3 + 4j
print(c * 2) # (6+8j)

```

---

#### **5. Perilaku Khusus**

- **Pembagian dengan nol** → Error:

```python

print(10 / 0) # ZeroDivisionError

```

- **Floor Division negatif**:

```python

print(-10 // 3) # -4 (pembulatan ke bawah)

```

- **Modulus dengan negatif**:

```python

print(10 % -3) # -2 (hasil mengikuti pembagi)

```

---

#### **6. Aplikasi Praktis**

1. **Konversi satuan**:

```python

# Celsius ke Fahrenheit

celsius = 25

fahrenheit = (celsius * 9/5) + 32

```
2. **Cek bilangan genap/ganjil**:

```python

angka = 7

if angka % 2 == 0:

print("Genap")

else:

print("Ganjil")

```

3. **Pemisahan digit**:

```python

number = 1234

ribuan = number // 1000 #1

ratusan = (number % 1000) // 100 # 2

```

---

### **Perbedaan Penting**

| Operator | Bedanya dengan Matematika Biasa |

|----------|----------------------------------------|

| `/` | Hasil selalu float (`10/2=5.0`) |

| `//` | Pembulatan ke bawah (`-10//3=-4`) |

| `%` | Modulus bisa negatif (`10%-3=-2`) |

---

### **Diagram Alur Operasi**

```
[Input Numerik]


[Pilih Operator] → (+, -, *, /, //, %, **)


[Proses Perhitungan]


[Output Hasil]

```

Operator aritmatika adalah fondasi pemrograman untuk:

- Kalkulasi bisnis (keuangan, inventori)

- Ilmu data (statistik, transformasi)

- Game development (fisika, pergerakan)

- Dan hampir semua aspek komputasi! 🧮🐍

- **Perbandingan (Comparison)**

### **Operator Perbandingan dalam Python**

Operator perbandingan (comparison operators) digunakan untuk


**membandingkan dua nilai** dan menghasilkan nilai boolean (`True`
atau `False`). Operator ini fundamental untuk pengambilan keputusan
dalam logika program seperti percabangan (`if`), perulangan (`while`),
dan filter data.

---

#### **Daftar Operator Perbandingan**


| Operator | Nama | Contoh | Hasil (dengan `a=10`,
`b=5`) |

|----------|--------------------------|--------------|-------------------------------|

| `==` | Sama dengan | `a == b` | `False` |

| `!=` | Tidak sama dengan | `a != b` | `True` |

| `>` | Lebih besar dari | `a > b` | `True` |

| `<` | Lebih kecil dari | `a < b` | `False` |

| `>=` | Lebih besar atau sama dengan | `a >= b` | `True`


|

| `<=` | Lebih kecil atau sama dengan | `a <= b` | `False`


|

---

#### **1. Contoh Implementasi Dasar**

```python

x = 15

y=7

print("x == y :", x == y) # False

print("x != y :", x != y) # True

print("x > y :", x > y) # True

print("x < y :", x < y) # False

print("x >= y :", x >= y) # True

print("x <= y :", x <= y) # False

```

---
#### **2. Perbandingan Tipe Data Berbeda**

- **Numerik**: Python konversi otomatis

```python

print(5 == 5.0) # True (int vs float)

```

- **String**: Bandingkan berdasarkan *lexicographical order* (urutan


ASCII/Unicode)

```python

print("apel" == "apel") # True

print("apel" < "jeruk") # True ('a' < 'j')

print("Apel" < "apel") # True (huruf besar < huruf kecil)

```

- **Boolean**: `True` = 1, `False` = 0

```python

print(True == 1) # True

print(False < 1) # True

```

---

#### **3. Perbandingan Struktur Data**

- **List/Tuple**: Bandingkan elemen per elemen

```python

print([1, 2] == [1, 2]) # True

print([1, 2] > [1, 1]) # True (elemen ke-2: 2 > 1)

```
- **Dictionary**: Bandingkan pasangan key-value

```python

dict1 = {'a': 1, 'b': 2}

dict2 = {'b': 2, 'a': 1}

print(dict1 == dict2) # True (urutan tidak pengaruh)

```

---

#### **4. Chained Comparisons (Perbandingan Berantai)**

Python mendukung kombinasi beberapa perbandingan:

```python

# Ekspresi matematika: 5 ≤ x ≤ 15

x = 10

print(5 <= x <= 15) # True (setara dengan 5<=x and x<=15)

# Contoh kompleks

print(3 < x//2 <= 7) # True (10//2=5 → 3<5 and 5<=7)

```

---

#### **5. Perilaku Khusus**

- **`is` vs `==`**:

```python

a = [1, 2]

b = [1, 2]

print(a == b) # True (nilai sama)

print(a is b) # False (objek berbeda di memori)


```

- **Perbandingan dengan `NaN`** (Not a Number):

```python

import math

nan = float('nan')

print(nan == nan) # False (spesial case!)

```

---

#### **6. Aplikasi Praktis**

1. **Validasi input**:

```python

usia = int(input("Usia: "))

if usia >= 18:

print("Anda dewasa")

else:

print("Anda minor")

```

2. **Filter data**:

```python

nilai = [75, 85, 90, 65]

lulus = [n for n in nilai if n >= 70]

```

3. **Kondisi kompleks**:

```python
suhu = 26

if 20 <= suhu <= 30:

print("Suhu nyaman")

```

---

#### **Urutan Prioritas Operator**

Operator perbandingan memiliki prioritas lebih rendah dari aritmatika:

```python

# Hitung dulu: 10+5 > 20-3 → 15 > 17 → False

hasil = 10 + 5 > 20 - 3

print(hasil) # Output: False

```

---

#### **Perbandingan Custom Class**

Anda bisa definisikan perilaku perbandingan dengan metode khusus:

```python

class Product:

def __init__(self, price):

[Link] = price

def __lt__(self, other): # Override operator <

return [Link] < [Link]

p1 = Product(100)

p2 = Product(200)
print(p1 < p2) # True

```

---

### **Visualisasi Alur Perbandingan**

```

[Nilai A]


[Operator] → [Nilai B]


True/False

```

Operator perbandingan adalah tulang punggung untuk:

- Logika bisnis (diskon, pajak)

- Validasi form

- Algoritma sorting

- Analisis data

Dengan menguasainya, Anda bisa membangun logika program yang lebih


cerdas! 🧠🐍

- **Logika (Logical)**

### **Operator Logika dalam Python**

Operator logika digunakan untuk **mengombinasikan pernyataan


boolean** (`True`/`False`) dan menghasilkan nilai boolean baru. Operator
ini fundamental untuk logika percabangan kompleks dan pengambilan
keputusan dalam program.

---

#### **Tiga Operator Logika Utama**

| Operator | Nama | Deskripsi |


Contoh |

|----------|---------|---------------------------------------------------------------------------|------
----------------------|

| `and` | AND | `True` hanya jika **kedua** operand `True`


| `x > 5 and x < 10` |

| `or` | OR | `True` jika **minimal satu** operand `True`


| `y == 0 or y == 100` |

| `not` | NOT | Membalikkan nilai boolean (`True` jadi `False`, `False`


jadi `True`) | `not is_active` |

---

#### **1. Tabel Kebenaran (Truth Table)**

|A |B | `A and B` | `A or B` | `not A` |

|-------|-------|-----------|----------|---------|

| True | True | **True** | True | False |

| True | False | False | **True** | False |

| False | True | False | **True** | True |

| False | False | False | False | True |

---
#### **2. Contoh Implementasi**

```python

# Contoh dasar

usia = 25

punya_sim = True

bisa_nyetir = usia >= 17 and punya_sim

print(bisa_nyetir) # Output: True

# Kombinasi OR

is_weekend = False

is_holiday = True

libur = is_weekend or is_holiday

print(libur) # Output: True

# Operator NOT

is_rainy = True

bisa_main = not is_rainy

print(bisa_main) # Output: False

```

---

#### **3. Short-Circuit Evaluation**

Python mengevaluasi ekspresi logika secara efisien:

- **`and`**: Berhenti di operand pertama yang `False`

- **`or`**: Berhenti di operand pertama yang `True`

```python
# Contoh short-circuit

def cek():

print("Fungsi dipanggil!")

return True

# OR: Berhenti di True pertama

print(True or cek()) # Output: True (tanpa panggil cek())

# AND: Berhenti di False pertama

print(False and cek()) # Output: False (tanpa panggil cek())

```

---

#### **4. Kombinasi dengan Operator Lain**

```python

# Validasi username

username = "user_123"

panjang_ok = len(username) >= 6

format_ok = "_" in username

if panjang_ok and format_ok:

print("Username valid!")

# Cek diskon

total_belanja = 750000

is_member = True

dapat_diskon = total_belanja > 500000 and is_member

```
---

#### **5. Prioritas Operator**

Urutan evaluasi (tinggi ke rendah):

1. `()` (Kurung)

2. `not`

3. `and`

4. `or`

```python

# Contoh prioritas

print(True or False and False) # → True or (False) → True

print((True or False) and False) # → (True) and False → False

```

---

#### **6. Aplikasi Praktis**

1. **Sistem login**:

```python

username_valid = username == "admin"

password_valid = password == "secret123"

if username_valid and password_valid:

print("Login berhasil!")

```

2. **Validasi form**:
```python

email = "user@[Link]"

is_email_valid = "@" in email and "." in email

```

3. **Game logic**:

```python

punya_kunci = True

monster_mati = False

bisa_buka_pintu = punya_kunci and not monster_mati

```

---

#### **7. Perilaku Khusus**

- **Truthy/Falsy Values**:

Operator logika bekerja dengan nilai non-boolean berdasarkan aturan


truthy/falsy:

```python

# Contoh Falsy: 0, "", [], None, False

print(0 or "default") # Output: "default"

print("" and 100) # Output: ""

```

- **Operator Bitwise vs Logika**:

```python

print(True & False) # Bitwise AND → 0 (False)

print(True and False) # Logical AND → False

```
---

### **Visualisasi Alur Logika**

```

Contoh: if (A and B) or C

┌───────────────┐

│ Evaluasi A │

└───┬───────────┘

┌──────┴───────┐

│ A True? │

└──────┬───────┘

┌────────┴─────────┐

│ Evaluasi B │

└────────┬─────────┘

┌────────┴─────────┐

│ Hasil (A and B) │

└────────┬─────────┘

┌────────┴─────────┐

│ Jika False: │

│ Evaluasi C │

└────────┬─────────┘

┌────────┴─────────┐

│ Hasil Akhir │
└──────────────────┘

```

---

### **Tips Penting**

1. Gunakan tanda kurung untuk ekspresi kompleks:

```python

# Lebih jelas

if (is_admin or is_moderator) and not is_banned:

```

2. Hindari rantai `not` yang panjang:

```python

# Sulit dibaca

if not not not condition:

# Lebih baik

if condition:

```

3. Manfaatkan short-circuit untuk optimasi:

```python

# Cek dulu yang ringan

if users and users[0] == 'admin':

```

Operator logika adalah jantung dari logika program yang kompleks.


Dengan menguasainya, Anda bisa membangun algoritma yang lebih
cerdas dan efisien! 🧠⚡️
- **Bitwise**

### **Operator Bitwise dalam Python**

Operator bitwise digunakan untuk **melakukan operasi langsung pada


bit** (biner) dari bilangan integer. Operator ini memanipulasi representasi
biner angka di tingkat paling rendah, sehingga sangat berguna untuk
pemrograman sistem, enkripsi, dan optimasi memori.

---

#### **Daftar Operator Bitwise**

| Operator | Nama | Contoh | Deskripsi


|

|----------|---------------|------------|---------------------------------------------------------------
------------|

| `&` | AND | `a & b` | Setiap bit hasil 1 hanya jika kedua bit
input 1 |

| `\|` | OR | `a \| b` | Setiap bit hasil 1 jika minimal satu bit input


1 |

| `^` | XOR | `a ^ b` | Setiap bit hasil 1 jika kedua bit input


berbeda |

| `~` | NOT | `~a` | Membalikkan semua bit (1 jadi 0, 0 jadi


1) |

| `<<` | Left Shift | `a << n` | Menggeser bit ke kiri sebanyak `n`,


tambahkan 0 di kanan |

| `>>` | Right Shift | `a >> n` | Menggeser bit ke kanan sebanyak


`n`, tambahkan 0 di kiri (bilangan positif) |

---

#### **1. Representasi Biner & Contoh**


Misal: `a = 5` (biner: `0101`), `b = 3` (biner: `0011`)

| Operator | Perhitungan | Biner | Desimal |

|----------|----------------------------|-------------|---------|

| `a & b` | `0101 & 0011` → `0001` | 1 |

| `a \| b` | `0101 \| 0011` → `0111` | 7 |

| `a ^ b` | `0101 ^ 0011` → `0110` | 6 |

| `~a` | `~0101` → `1010`* | -6 |

| `a << 1` | `0101` digeser kiri 1 bit → `1010` | 10 |

| `a >> 1` | `0101` digeser kanan 1 bit → `0010` | 2 |

> *Catatan: Python menggunakan [two's


complement]([Link] untuk
bilangan negatif.

---

#### **2. Contoh Kode Python**

```python

a = 5 # 0101

b = 3 # 0011

print("AND :", a & b) # 1 (0001)

print("OR :", a | b) # 7 (0111)

print("XOR :", a ^ b) # 6 (0110)

print("NOT a:", ~a) # -6 (dalam two's complement)

print("Left Shift :", a << 1) # 10 (1010)

print("Right Shift:", a >> 1) # 2 (0010)

```
---

#### **3. Aplikasi Praktis**

1. **Enkripsi Sederhana** (XOR Cipher):

```python

pesan = 123

kunci = 456

enkripsi = pesan ^ kunci

dekripsi = enkripsi ^ kunci

print(dekripsi) # Output: 123

```

2. **Cek Bilangan Genap/Ganjil**:

```python

angka = 7

if angka & 1: # Bit terakhir 1 = ganjil

print("Ganjil")

```

3. **Manipulasi Bit Flags**:

```python

# Flags permission: READ=1 (001), WRITE=2 (010), EXECUTE=4 (100)

permission = 1 | 2 # READ + WRITE (011)

print("Bisa baca?", bool(permission & 1)) # True

```

4. **Fast Multiplication/Division**:

```python

angka = 8
print(angka << 1) # 16 (×2)

print(angka >> 2) # 2 (÷4)

```

---

#### **4. Perilaku Khusus**

- **Bilangan Negatif**:

```python

print(~5) # Output: -6 (karena ~x = -x-1)

print(-6 & 0xFF) # Masking: 250 (mengambil 8 bit terakhir)

```

- **Right Shift pada Bilangan Negatif**:

```python

print(-8 >> 1) # Output: -4 (Python mempertahankan tanda)

```

- **Bitwise vs Logical Operators**:

```python

print(5 & 3) # Bitwise AND → 1

print(5 and 3) # Logical AND → 3 (truthy value)

```

---

#### **5. Tabel Kebenaran Bitwise**

| A | B | A & B | A \| B | A ^ B |
|---|---|-------|--------|-------|

|0|0|0 |0 |0 |

|0|1|0 |1 |1 |

|1|0|0 |1 |1 |

|1|1|1 |1 |0 |

---

#### **6. Operator Gabungan (Augmented Assignment)**

```python

x = 10

x &= 7 # Sama dengan: x = x & 7 → 2 (1010 & 0111 = 0010)

x <<= 2 # x = 2 << 2 → 8

```

---

### **Visualisasi Operasi Shift**

```

Left Shift (<<):

5 << 1: 0101 → 1010 (10)

Right Shift (>>):

5 >> 1: 0101 → 0010 (2)

```

---

### **Kapan Menggunakan Bitwise?**


1. **Sistem Embedded** & Pemrograman dekat hardware

2. **Algoritma Kriptografi** (XOR, rotasi bit)

3. **Kompresi Data** (manipulasi bit-level)

4. **Optimasi Memori** (packing data dalam bit flags)

5. **Jaringan Komputer** (subnet masking)

Contoh subnet mask:

```python

ip = 192 << 24 | 168 << 16 | 1 << 8 | 1 # [Link]

mask = 0xFFFFFF00 # [Link]

network = ip & mask # Network address

```

---

### **Perbandingan dengan Bahasa Lain**

| Fitur | Python | C/C++ | Catatan |

|----------------|--------|-------------|----------------------------------|

| Tipe bilangan | Integer| Integer | |

| Ukuran bit | Dinamis| Tetap | Python handle big integer otomatis |

| Shift negatif | Sign-extended | Bergantung compiler | Python


pertahankan tanda |

Operator bitwise memberi Anda kontrol tingkat rendah yang powerful,


meskipun jarang digunakan dalam pemrograman aplikasi sehari-hari.
Dengan memahami konsep ini, Anda bisa bekerja lebih efektif di bidang
sistem, keamanan, dan embedded programming! ⚙️🔐

- **Penugasan (Assignment)**

### **Operator Penugasan dalam Python**


Operator penugasan (assignment operators) digunakan untuk
**memberikan nilai ke variabel**. Operator dasar adalah `=`, tetapi
Python juga menyediakan operator penugasan gabungan (*compound
assignment*) yang menggabungkan operasi aritmatika/bitwise dengan
penugasan.

---

#### **1. Operator Penugasan Dasar (`=`)**

Menyimpan nilai di sebelah kanan ke variabel di sebelah kiri:

```python

x = 10

nama = "Budi"

is_valid = True

```

---

#### **2. Operator Penugasan Gabungan**

Menyingkat operasi seperti `x = x + 5` menjadi `x += 5`:

| Operator | Contoh | Setara dengan | Operasi |

|----------|--------------|---------------|---------------------|

| `+=` | `x += 5` | `x = x + 5` | Penjumlahan |

| `-=` | `x -= 3` | `x = x - 3` | Pengurangan |

| `*=` | `x *= 2` | `x = x * 2` | Perkalian |

| `/=` | `x /= 4` | `x = x / 4` | Pembagian |

| `//=` | `x //= 3` | `x = x // 3` | Floor Division |

| `%=` | `x %= 5` | `x = x % 5` | Modulus |
| `**=` | `x **= 2` | `x = x ** 2` | Pangkat |

| `&=` | `x &= 3` | `x = x & 3` | Bitwise AND |

| `|=` | `x |= 1` | `x = x | 1` | Bitwise OR |

| `^=` | `x ^= 2` | `x = x ^ 2` | Bitwise XOR |

| `<<=` | `x <<= 1` | `x = x << 1` | Left Shift |

| `>>=` | `x >>= 1` | `x = x >> 1` | Right Shift |

---

#### **3. Contoh Penggunaan**

```python

# Contoh numerik

counter = 5

counter += 3 # counter = 8

counter *= 2 # counter = 16

counter %= 5 # counter = 1 (16 % 5 = 1)

# Contoh string

teks = "Py"

teks += "thon" # teks = "Python"

# Contoh bitwise

flags = 0b0001

flags |= 0b0010 # flags = 0b0011 (3)

flags <<= 2 # flags = 0b1100 (12)

```

---
#### **4. Multiple Assignment**

Python mendukung penugasan banyak variabel sekaligus:

```python

# Satu nilai ke banyak variabel

a = b = c = 0 # a=0, b=0, c=0

# Banyak nilai ke banyak variabel (tuple unpacking)

x, y, z = 1, 2, 3 # x=1, y=2, z=3

# Tukar nilai tanpa variabel sementara

x, y = y, x # Tukar nilai x dan y

```

---

#### **5. Penugasan dengan Struktur Data**

```python

# List unpacking

numbers = [10, 20, 30]

a, b, c = numbers # a=10, b=20, c=30

# Extended unpacking (Python 3+)

first, *rest = [1, 2, 3, 4] # first=1, rest=[2,3,4]

# Dictionary key assignment

data = {}

data['nama'] = 'Budi'

data['umur'] = 25

```
---

#### **6. Perilaku Khusus**

- **Penugasan ke ekspresi**: Tidak diperbolehkan

```python

10 = x # Error: SyntaxError

```

- **Type consistency**: Nilai harus kompatibel

```python

text = "Nilai: "

text += 10 # TypeError: must be str, not int

text += str(10) # Benar: "Nilai: 10"

```

- **Mutability**: Hati-hati dengan objek mutable

```python

list1 = list2 = [] # Dua referensi ke objek sama

[Link](1)

print(list2) # Output: [1]

```

---

#### **7. Contoh Praktis**

1. **Akumulasi nilai dalam loop**:

```python

total = 0
for i in range(1, 6):

total += i # total = 15

```

2. **Update konfigurasi**:

```python

config = {'verbose': False}

config['verbose'] |= True # Menjadi True

```

3. **Pemrosesan string**:

```python

output = "Hasil: "

for num in [1.5, 2.8, 3.2]:

output += f"{num:.0f}, " # "Hasil: 2, 3, 3, "

```

---

### **Diagram Alur Penugasan**

```

[Nilai/Sumber]


[Operator] → [Variabel Target]


Nilai disimpan di variabel

```
---

### **Perbedaan Penting**

| Operator | Bedanya dengan `=` Biasa | Keuntungan |

|----------|-------------------------------|--------------------------|

| `+=` | Lebih ringkas | Hemat penulisan kode |

| `*=` | Operasi dilakukan in-place | Efisien untuk objek besar|

| `,=` (unpacking)| Bisa banyak variabel sekaligus | Praktis untuk tuple/list


|

Operator penugasan adalah dasar dari semua operasi pemrograman di


Python. Dengan memahami berbagai bentuknya, Anda bisa menulis kode
yang lebih efisien dan ekspresif! 💻🚀

- **Keanggotaan (Membership)**

### **Operator Membership dalam Python**

Operator membership digunakan untuk **memeriksa keanggotaan**


(apakah suatu nilai ada di dalam struktur data seperti string, list, tuple,
set, atau dictionary). Operator ini menghasilkan nilai boolean (`True` atau
`False`).

---

#### **Dua Operator Membership Utama**

| Operator | Contoh | Deskripsi |

|----------|------------------|------------------------------------------------|

| `in` | `x in y` | `True` jika nilai `x` ada di `y` |

| `not in` | `x not in y` | `True` jika nilai `x` **tidak** ada di `y` |
---

#### **1. Contoh Implementasi**

```python

# String

teks = "Belajar Python"

print("Py" in teks) # True

print("Java" not in teks) # True

# List

buah = ["apel", "mangga", "jeruk"]

print("mangga" in buah) # True

print(100 in buah) # False

# Tuple

warna = ("merah", "hijau", "biru")

print("kuning" not in warna) # True

# Set

prima = {2, 3, 5, 7}

print(3 in prima) # True

```

---

#### **2. Perilaku Khusus di Dictionary**

- Secara default, operator membership memeriksa **kunci (keys)**


- Untuk nilai (values) atau items, gunakan `.values()` atau `.items()`

```python

data = {"nama": "Budi", "umur": 25, "kota": "Jakarta"}

# Cek key

print("nama" in data) # True

print("Budi" in data) # False (bukan key)

# Cek value

print("Budi" in [Link]()) # True

# Cek pasangan key-value

print(("umur", 25) in [Link]()) # True

```

---

#### **3. Efisiensi Operator Membership**

| Struktur Data | `in` Operator | Kompleksitas Waktu | Catatan


|

|---------------|---------------|-------------------|-----------------------------|

| List/Tuple | O(n) | Linear | Lambat untuk data besar |

| Set/Dict | O(1) | Konstan | Sangat cepat |

| String | O(n) | Linear | Tergantung panjang string |

Contoh perbandingan kecepatan:

```python
# Lebih efisien menggunakan set

large_list = list(range(1000000))

large_set = set(large_list)

# Cek angka 999999

%timeit 999999 in large_list # ~4.8 ms (lambat)

%timeit 999999 in large_set # ~0.0001 ms (cepat)

```

---

#### **4. Aplikasi Praktis**

1. **Validasi input**:

```python

pilihan = input("Pilih warna (merah/hijau/biru): ")

if [Link]() not in ["merah", "hijau", "biru"]:

print("Warna tidak valid!")

```

2. **Filter data**:

```python

email = "user@[Link]"

if "@" in email and "." in email:

print("Format email valid")

```

3. **Pengecekan substring**:

```python

log = "ERROR: File not found"


if "ERROR" in log:

send_alert()

```

---

#### **5. Implementasi Custom Class**

Anda bisa mendefinisikan perilaku `in` dengan metode `__contains__`:

```python

class Inventory:

def __init__(self, items):

[Link] = items

def __contains__(self, item):

return item in [Link]

gudang = Inventory(["apel", "mangga", "jeruk"])

print("apel" in gudang) # True

print("pisang" in gudang) # False

```

---

#### **6. Perbedaan dengan Operator Perbandingan**

| Fitur | Membership (`in`) | Perbandingan (`==`, `>`, dll) |

|----------------|---------------------|------------------------------|

| Fungsi | Cek keanggotaan | Bandingkan nilai |

| Tipe Output | Boolean | Boolean |

| Contoh | `"a" in ["a","b"]` | `5 == 5` |


| Penerapan | Struktur data | Nilai individual |

---

### **Visualisasi Alur Pengecekan Membership**

```

Mulai


[Ambil elemen x]


[Cari di struktur data y]


[Ditemukan?] ─── Ya ───→ True

Tidak


False

```

---

### **Peringatan Penting**

1. **Case Sensitivity**:

```python

print("A" in "apple") # False


print("a" in "Apple".lower()) # True

```

2. **Tipe Data Harus Cocok**:

```python

print(1 in ["1", "2", "3"]) # False (int vs string)

```

3. **Batas Pengecekan**:

```python

# Hanya cek 1 level

data = [[1, 2], [3, 4]]

print(1 in data) # False (1 tidak ada di list utama)

```

---

### **Kapan Menggunakan?**

1. Validasi data sebelum pemrosesan

2. Pencarian cepat dalam kumpulan data

3. Pemeriksaan konfigurasi sistem

4. Filtering log atau error monitoring

5. Implementasi fitur pencarian

Operator membership membuat kode lebih:

- **Ekspresif**: `if item in collection` lebih jelas daripada loop manual

- **Efisien**: Khususnya untuk set/dictionary

- **Pythonic**: Sesuai filosofi "Readability counts" di Python


Dengan menguasai operator ini, Anda bisa menulis kode yang lebih bersih
dan efisien! 🐍🔍

-----------------------------------------------------------------------

#### **5. Fungsi**

- **Parameter vs Argumen**

### **Fungsi: Parameter vs Argument dalam Python**

Perbedaan antara **parameter** dan **argument** adalah konsep


fundamental dalam pemrograman fungsi. Berikut penjelasan lengkap
dengan contoh:

---

#### **1. Parameter (Parameter)**

- **Definisi**: Variabel yang dideklarasikan di dalam **tanda kurung


fungsi** saat pendefinisian fungsi.

- **Fungsi**: Bertindak sebagai *placeholder* untuk nilai yang akan


dioperasikan di dalam fungsi.

- **Analog**: Seperti "formulir kosong" yang harus diisi.

```python

# x dan y adalah PARAMETER

def tambah(x, y):

return x + y

```

---

#### **2. Argument (Argumen)**


- **Definisi**: Nilai aktual yang **dikirimkan ke fungsi** saat pemanggilan.

- **Fungsi**: Mengisi parameter dengan nilai konkret untuk diproses.

- **Analog**: Seperti "data nyata" yang diisikan ke formulir.

```python

# 5 dan 3 adalah ARGUMEN

hasil = tambah(5, 3)

print(hasil) # Output: 8

```

---

#### **3. Visualisasi Proses**

```

Pendefinisian Fungsi:

def fungsi(parameter1, parameter2):

...kode...

Pemanggilan Fungsi:

fungsi(argument1, argument2)

```

---

#### **4. Jenis-Jenis Parameter**

| Jenis Parameter | Contoh | Deskripsi |

|-----------------------|-------------------------|------------------------------------|

| Posisi (Positional) | `def f(a, b):` | Diisi berdasarkan urutan |


| Default | `def f(a, b=0):` | Nilai bawaan jika argumen tidak
ada |

| Keyword | `def f(*args):` | Menerima banyak argumen


posisi |

| Variadic (Arbitrary) | `def f(**kwargs):` | Menerima banyak argumen


keyword |

---

#### **5. Jenis-Jenis Argument**

| Jenis Argument | Contoh | Deskripsi |

|-----------------------|-------------------------|------------------------------------|

| Posisi (Positional) | `f(1, 2)` | Diisi berdasarkan urutan


parameter |

| Keyword (Named) | `f(b=2, a=1)` | Diisi berdasarkan nama


parameter |

| Default | `f(1)` | Menggunakan nilai default


parameter|

| Variadic (Arbitrary) | `f(1, 2, 3)` atau `f(a=1, b=2)` | Menggunakan


`*args` atau `**kwargs` |

---

#### **6. Contoh Kombinasi**

```python

# Fungsi dengan berbagai jenis parameter

def contoh(a, b=0, *args, **kwargs):

print(f"a={a}, b={b}, args={args}, kwargs={kwargs}")

# Pemanggilan dengan berbagai argument

contoh(10) # a=10, b=0, args=(), kwargs={}


contoh(5, 2) # a=5, b=2, args=(), kwargs={}

contoh(1, 2, 3, 4) # a=1, b=2, args=(3,4), kwargs={}

contoh(7, c=9, d=10) # a=7, b=0, args=(), kwargs={'c':9,


'd':10}

contoh(8, 9, 10, 11, e=12, f=13) # a=8, b=9, args=(10,11),


kwargs={'e':12, 'f':13}

```

---

#### **7. Kesalahan Umum**

1. **Argument posisi setelah keyword**:

```python

contoh(a=1, 2) # Error: positional argument after keyword argument

```

2. **Parameter wajib tidak terisi**:

```python

tambah(5) # TypeError: missing required argument 'y'

```

3. **Argument berlebihan**:

```python

def f(a): pass

f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given

```

---

#### **8. Best Practices**


1. **Urutan Parameter**:

```

[Positional] → [*args] → [Default] → [**kwargs]

```

Contoh benar:

```python

def good(a, b=0, *args, **kwargs):

```

2. **Gunakan keyword argument** untuk kejelasan:

```python

# Tidak jelas

hitung_volume(10, 5, 2)

# Lebih jelas

hitung_volume(panjang=10, lebar=5, tinggi=2)

```

3. **Batasi jumlah parameter** (maks 3-4), gunakan struktur data jika


kompleks:

```python

# Daripada:

def update_user(id, nama, email, alamat, telepon):

# Lebih baik:

def update_user(user_id, **attributes):

```

---
#### **Diagram Alur Fungsi**

```

Pemanggilan Fungsi:

[Argument]

Fungsi → [Parameter]

[Proses]

[Return Value]

```

---

### **Perbedaan Kunci**

| Karakteristik | Parameter | Argument |

|--------------------|-------------------------------|------------------------------|

| **Lokasi** | Definisi fungsi | Pemanggilan fungsi |

| **Nilai** | Formal/placeholder | Aktual/nyata |

| **Tipe** | Wajib/default/*args/**kwargs | Posisi/keyword/variadic


|

| **Contoh Sintaks** | `def f(x, y):` | `f(5, 10)` |

Dengan memahami perbedaan ini, Anda akan:

- Menghindari error sintaksis umum

- Menulis fungsi lebih fleksibel

- Membuat kode lebih mudah dibaca dan dipelihara

- Menguasai teknik pemrograman lanjut seperti decorators dan partial


functions
Parameter dan argument adalah jantung dari fungsi Python. Penguasaan
konsep ini membuka pintu untuk desain kode yang lebih modular dan
powerful! 🚀

- **Jenis Fungsi**:

- Bawaan (Built-in)

### **Jenis Fungsi Bawaan (Built-in Functions) dalam Python**

Fungsi bawaan adalah fungsi yang **sudah terintegrasi dalam Python**


dan selalu tersedia tanpa perlu mengimpor modul tambahan. Fungsi ini
menyediakan operasi dasar yang sering digunakan untuk memanipulasi
data, konversi tipe, matematika, dan banyak lagi.

---

#### **Kategori Utama Fungsi Bawaan**

1. **Fungsi Konversi Tipe Data**

Mengubah tipe data objek:

```python

int("10") # 10 (string → integer)

float(5) # 5.0 (integer → float)

str(3.14) # "3.14" (float → string)

list("abc") # ['a', 'b', 'c'] (string → list)

tuple([1,2,3]) # (1,2,3) (list → tuple)

set([1,1,2]) # {1,2} (list → set)

dict([(1,'a'), (2,'b')]) # {1:'a', 2:'b'}

```

2. **Fungsi Matematika & Numerik**


Operasi matematika dasar:

```python

abs(-5) # 5 (nilai absolut)

pow(2, 3) # 8 (2 pangkat 3)

round(3.14159, 2) # 3.14 (pembulatan)

divmod(10, 3) # (3, 1) (hasil bagi dan sisa)

```

3. **Fungsi Iterasi & Loop**

Memproses koleksi data:

```python

range(5) # Generator: 0,1,2,3,4

len([10,20,30]) # 3 (panjang objek)

sorted([3,1,2]) # [1,2,3] (pengurutan)

reversed("abc") # Iterator: 'c','b','a'

```

4. **Fungsi Input/Output**

Interaksi dengan pengguna:

```python

input("Nama: ") # Membaca input user

print("Hello!") # Mencetak output

```

5. **Fungsi Pemeriksaan Tipe**

Mengecek jenis objek:

```python

type("text") # <class 'str'>

isinstance(5, int) # True


issubclass(bool, int) # True (bool subclass int)

```

6. **Fungsi Boolean & Logika**

Operasi logika:

```python

bool(0) # False (truthiness)

all([True, False]) # False

any([True, False]) # True

```

---

#### **Contoh Lengkap 20+ Fungsi Bawaan Penting**

| Fungsi | Contoh | Hasil | Deskripsi |

|--------|--------|-------|----------|

| `abs()` | `abs(-7)` | 7 | Nilai absolut |

| `bin()` | `bin(10)` | '0b1010' | Representasi biner |

| `chr()` | `chr(65)` | 'A' | Karakter dari ASCII |

| `enumerate()` | `list(enumerate(['a','b']))` | `[(0,'a'),(1,'b')]` | Beri indeks


iterasi |

| `filter()` | `list(filter(lambda x: x>0, [-1,0,2]))` | `[2]` | Filter elemen |

| `format()` | `format(0.25, '.0%')` | '25%' | Format tampilan |

| `hash()` | `hash("python")` | 3715897350 | Hash objek |

| `help()` | `help(str)` | Manual string | Bantuan interaktif |

| `hex()` | `hex(255)` | '0xff' | Representasi heksadesimal |

| `id()` | `id([1,2])` | 140123456 | Alamat memori objek |

| `map()` | `list(map([Link], ['a','b']))` | `['A','B']` | Transformasi elemen


|
| `max()` | `max([3,1,4])` | 4 | Nilai maksimum |

| `min()` | `min([3,1,4])` | 1 | Nilai minimum |

| `oct()` | `oct(8)` | '0o10' | Representasi oktal |

| `open()` | `open('[Link]')` | File object | Buka file |

| `ord()` | `ord('A')` | 65 | Kode ASCII karakter |

| `sum()` | `sum([1,2,3])` | 6 | Jumlah elemen |

| `super()` | `super().__init__()` | Akses parent class | Pemanggilan


superclass |

| `zip()` | `list(zip([1,2], ['a','b']))` | `[(1,'a'),(2,'b')]` | Gabungkan iterable |

---

#### **Perbedaan Fungsi Bawaan vs Modul Standar**

| Karakteristik | Fungsi Bawaan | Fungsi Modul Standar |

|---------------|---------------|----------------------|

| **Akses** | Langsung tanpa impor | Harus impor modul |

| **Contoh** | `print()`, `len()` | `[Link]()`, `[Link]()` |

| **Jumlah** | ≈ 70+ fungsi | Ribuan fungsi |

| **Namespace** | `__builtins__` | Modul spesifik |

Cek semua fungsi bawaan:

```python

import builtins

print(dir(builtins)) # Tampilkan semua built-in functions

```

---

#### **Best Practices Penggunaan**


1. **Hindari shadowing**:

```python

# ❌ Jangan timpa fungsi bawaan

str = "custom" # Menghilangkan akses ke str()

```

2. **Ganti loop dengan `map()`/`filter()`**:

```python

# Daripada:

result = []

for x in [1,2,3]:

[Link](x*2)

# Lebih baik:

result = list(map(lambda x: x*2, [1,2,3]))

```

3. **Manfaatkan `enumerate()` untuk indeks**:

```python

for i, item in enumerate(['a','b','c']):

print(f"Index {i}: {item}")

```

---

### **Aplikasi Praktis**

1. **Konversi suhu**:

```python

celsius = 30
fahrenheit = float(celsius) * 9/5 + 32

```

2. **Validasi password**:

```python

password = "Secret123"

is_valid = any([Link]() for c in password) and len(password) >= 8

```

3. **Proses file**:

```python

with open('[Link]') as file:

lines = list(map([Link], [Link]()))

```

---

### **Visualisasi Eksekusi Fungsi Bawaan**

```

Input → [Fungsi Bawaan] → Output


[Proses Internal]


Hasil

```

Fungsi bawaan adalah alat inti Python untuk:


- Mempercepat pengembangan

- Menulis kode lebih ringkas

- Melakukan operasi umum secara efisien

- Menjaga konsistensi kode

Dengan menguasai fungsi bawaan, Anda bisa menyelesaikan tugas


pemrograman 2-5× lebih cepat! ⚡️🐍

- Pengguna (User-defined)

### Jenis Fungsi Pengguna (User-Defined Functions) dalam Python

Dalam Python, **jenis fungsi pengguna** mengacu pada fungsi yang


dibuat oleh programmer sendiri (bukan fungsi bawaan Python). Fungsi-
fungsi ini diklasifikasikan berdasarkan cara mereka **didefinisikan** dan
**digunakan**. Berikut jenis-jenis utama beserta contohnya:

#### 1. Fungsi Tanpa Argumen dan Tanpa Return

```python

def sapa():

print("Selamat pagi, siswa!")

sapa() # Output: Selamat pagi, siswa!

```

#### 2. Fungsi dengan Argumen tapi Tanpa Return

```python

def hitung_total(nilai_tugas, nilai_ujian):

total = nilai_tugas * 0.4 + nilai_ujian * 0.6

print(f"Total nilai: {total:.2f}")


hitung_total(80, 75) # Output: Total nilai: 77.00

```

#### 3. Fungsi dengan Argumen dan Return Value

```python

def hitung_rata(nilai1, nilai2, nilai3):

return (nilai1 + nilai2 + nilai3) / 3

rata_siswa = hitung_rata(85, 90, 78)

print(f"Rata-rata: {rata_siswa:.2f}") # Output: Rata-rata: 84.33

```

#### 4. Fungsi dengan Nilai Default Argument

```python

def catat_kehadiran(nama, status="Hadir"):

print(f"{nama}: {status}")

catat_kehadiran("Budi") # Output: Budi: Hadir

catat_kehadiran("Ani", "Izin") # Output: Ani: Izin

```

#### 5. Fungsi dengan Keyword Arguments

```python

def buat_laporan(nama, kelas, nilai):

print(f"Laporan {nama} (Kelas {kelas}): Nilai {nilai}")

buat_laporan(nilai=85, kelas="9A", nama="Cici")

# Output: Laporan Cici (Kelas 9A): Nilai 85

```
#### 6. Fungsi dengan Variable-Length Arguments (`*args`)

```python

def hitung_total_nilai(*nilai_siswa):

return sum(nilai_siswa)

print(hitung_total_nilai(75, 80, 85, 90)) # Output: 330

```

#### 7. Fungsi dengan Keyword Variable-Length Arguments (`**kwargs`)

```python

def buat_profil_siswa(**data):

for key, value in [Link]():

print(f"{key}: {value}")

buat_profil_siswa(

nama="Dodi",

kelas="10 IPA",

ekstrakurikuler=["Robotik", "Pramuka"]

# Output:

# nama: Dodi

# kelas: 10 IPA

# ekstrakurikuler: ['Robotik', 'Pramuka']

```

#### 8. Fungsi Lambda (Fungsi Anonim)

```python

hitung_pangkat = lambda x, y: x ** y
print(hitung_pangkat(3, 2)) # Output: 9

# Contoh di kelas:

siswa_berprestasi = lambda nilai: nilai >= 90

print(siswa_berprestasi(88)) # Output: False

```

#### 9. Fungsi Rekursif

```python

def faktorial(n):

return 1 if n == 0 else n * faktorial(n-1)

print(faktorial(5)) # Output: 120

```

#### 10. Fungsi dalam Fungsi (Nested Functions)

```python

def pengolah_nilai():

def konversi_huruf(nilai):

if nilai >= 90: return 'A'

elif nilai >= 80: return 'B'

elif nilai >= 70: return 'C'

else: return 'D'

print(f"Predikat: {konversi_huruf(85)}")

pengolah_nilai() # Output: Predikat: B

```
#### 11. Fungsi Generator (dengan `yield`)

```python

def generate_nis(prefix, start, end):

current = start

while current <= end:

yield f"{prefix}-{current}"

current += 1

for nis in generate_nis("S2023", 1001, 1005):

print(nis)

# Output:

# S2023-1001

# S2023-1002

# S2023-1003

# S2023-1004

# S2023-1005

```

### Perbandingan dengan Fungsi Bawaan

| Karakteristik | Fungsi Pengguna | Fungsi Bawaan |

|------------------------|--------------------------------|----------------------------|

| Definisi | Diciptakan programmer | Sudah disediakan


Python |

| Contoh | `hitung_rata()` | `print()`, `len()` |

| Fleksibilitas | Sangat fleksibel | Tetap |

| Penamaan | Bebas (sesuai kebutuhan) | Nama sudah


ditentukan |

| Tingkat Kompleksitas | Dapat sangat kompleks | Umumnya


sederhana |
### Best Practices Fungsi Pengguna:

1. **Nama Deskriptif**: `hitung_rata_nilai()` lebih baik dari `hitung()`

2. **Satu Fungsi Satu Tugas**: Fokus pada satu pekerjaan spesifik

3. **Gunakan Docstring**:

```python

def konversi_nilai(nilai):

"""

Mengkonversi nilai angka ke huruf

Args:

nilai (int): Nilai 0-100

Returns:

str: Predikat A/B/C/D

"""

# Implementasi...

```

4. **Batasi 3-4 Parameter**: Jika lebih, pertimbangkan menggunakan


dictionary

5. **Hindari Efek Samping**: Fungsi sebaiknya tidak mengubah variabel


global

Fungsi pengguna adalah tulang punggung pemrograman modular di


Python, memungkinkan Anda membagi program kompleks seperti sistem
manajemen sekolah menjadi bagian-bagian kecil yang lebih terkelola.

- Lambda

### Fungsi Lambda dalam Python: Penjelasan Lengkap

Fungsi lambda (juga disebut **fungsi anonim**) adalah jenis fungsi khusus
di Python yang memiliki karakteristik unik:
#### 🎯 Ciri Utama Fungsi Lambda:

1. **Tanpa Nama** (anonymous function)

2. **Didefinisikan dalam 1 Baris**

3. **Hanya Boleh Berisi 1 Ekspresi**

4. **Tidak Menggunakan `return`** (nilai otomatis dikembalikan)

5. **Sintaks Minimalis**: `lambda arguments: expression`

#### ⚙️Sintaks Dasar:

```python

lambda parameter1, parameter2: operasi_parameter

```

#### 💡 Contoh Praktis:

```python

# Fungsi biasa

def kuadrat(x):

return x ** 2

# Fungsi lambda setara

lambda_kuadrat = lambda x: x ** 2

print(kuadrat(5)) # Output: 25

print(lambda_kuadrat(5)) # Output: 25

```

#### 🔑 Perbedaan Penting vs Fungsi Biasa (`def`):

| Karakteristik | Fungsi Lambda | Fungsi Biasa (`def`) |

|------------------------|----------------------------|----------------------------|
| **Nama** | Anonim (tanpa nama) | Memiliki nama |

| **Jumlah Ekspresi** | Hanya 1 ekspresi | Banyak


ekspresi/pernyataan |

| **Penggunaan** | Untuk operasi sederhana | Untuk logika


kompleks |

| **Fleksibilitas** | Terbatas | Lebih fleksibel |

| **Return Statement** | Tidak diperlukan | Diperlukan |

#### 💻 Contoh Penggunaan Umum:

1. **Sorting dengan Kustom Key**:

```python

siswa = [

{"nama": "Budi", "nilai": 85},

{"nama": "Ani", "nilai": 92},

{"nama": "Cici", "nilai": 78}

# Urutkan berdasarkan nilai (descending)

siswa_terurut = sorted(siswa, key=lambda x: x["nilai"], reverse=True)

print(siswa_terurut)

# Output: [{'nama': 'Ani', 'nilai': 92}, {'nama': 'Budi', 'nilai': 85}, {'nama':
'Cici', 'nilai': 78}]

```

2. **Filtering Data**:

```python

angka = [12, 7, 15, 3, 20, 9, 5]


# Filter angka ganjil

angka_ganjil = list(filter(lambda x: x % 2 != 0, angka))

print(angka_ganjil) # Output: [7, 3, 9, 5]

```

3. **Transformasi Data dengan `map()`**:

```python

nilai_ujian = [75, 80, 65, 90, 55]

# Tambah bonus 5 poin

nilai_plus_bonus = list(map(lambda x: x + 5, nilai_ujian))

print(nilai_plus_bonus) # Output: [80, 85, 70, 95, 60]

```

4. **Perhitungan Cepat**:

```python

# Kalkulator sederhana

operasi = {

"tambah": lambda a, b: a + b,

"kurang": lambda a, b: a - b,

"kali": lambda a, b: a * b

print(operasi["tambah"](10, 5)) # Output: 15

print(operasi["kali"](7, 8)) # Output: 56

```
#### 🚫 Batasan Fungsi Lambda:

1. Tidak bisa berisi pernyataan/perintah (`if`, `for`, `while`, dll)

2. Tidak bisa memiliki anotasi tipe

3. Tidak bisa berisi dokumentasi (docstring)

4. Sulit dibaca jika terlalu kompleks

#### ✅ Best Practices:

1. Gunakan untuk operasi **sederhana** 1-baris

2. Hindari untuk logika kompleks

3. Beri nama variabel penampung yang deskriptif

4. Gunakan dengan fungsi `map()`, `filter()`, `sorted()`

#### ⚠️Contoh Penggunaan Salah:

```python

# Terlalu kompleks (hindari!)

lambda_salah = lambda x: (

print("Memproses..."),

x ** 2 if x > 0 else 0,

print("Selesai")

)[1]

```

#### 💡 Alternatif yang Lebih Baik:

Untuk kasus kompleks, gunakan fungsi biasa:

```python

def hitung_kuadrat(x):

"""Hitung kuadrat bilangan positif"""

if x <= 0:

return 0
return x ** 2

```

### Kesimpulan:

Fungsi lambda adalah alat yang powerful untuk:

- Operasi transformasi data cepat

- Kustomisasi fungsi built-in

- Membuat kode lebih ringkas

Tapi gunakan dengan bijak hanya untuk operasi sederhana! Untuk logika
kompleks, tetap gunakan fungsi biasa (`def`).

- **Sintaks & Modularitas**

### Sintaks Fungsi dalam Python

Sintaks fungsi dalam Python mengacu pada struktur dan aturan penulisan
untuk mendefinisikan fungsi. Berikut komponen utamanya:

#### 1. Struktur Dasar

```python

def nama_fungsi(parameter1, parameter2):

"""Docstring (opsional)"""

# Badan fungsi

hasil = parameter1 + parameter2

return hasil

```

#### 2. Komponen Utama

a. **Keyword `def`**

Menandai awal definisi fungsi


b. **Nama Fungsi**

Mengikuti aturan penamaan variabel (snake_case disarankan)

c. **Parameter**

Dalam tanda kurung `()`, bisa:

- Positional parameters: `(a, b)`

- Default parameters: `(a, b=5)`

- Variable-length: `(*args)` atau `(**kwargs)`

d. **Titik Dua (`:`)**

Menandai akhir deklarasi parameter

e. **Docstring** (opsional)

String dokumentasi dalam triple quotes `""" """`

f. **Badan Fungsi**

Blok kode yang di-indentasi (spasi 4)

g. **Keyword `return`**

Mengembalikan nilai (opsional, default `None`)

#### 3. Contoh Lengkap

```python

def hitung_rata(nilai1, nilai2, nilai3, pembagi=3):

"""

Menghitung rata-rata tiga nilai

Args:

nilai1 (float): Nilai pertama


nilai2 (float): Nilai kedua

nilai3 (float): Nilai ketiga

pembagi (int): Pembagi (default=3)

Returns:

float: Rata-rata nilai

"""

total = nilai1 + nilai2 + nilai3

return total / pembagi

# Pemanggilan fungsi

rata_siswa = hitung_rata(85, 90, 78)

print(f"Rata-rata: {rata_siswa:.2f}") # Output: Rata-rata: 84.33

```

---

### Modularitas Fungsi dalam Python

Modularitas adalah praktik memecah program menjadi modul-modul


(fungsi) independen yang saling berinteraksi. Berikut konsep intinya:

#### 1. Prinsip Modularitas

- **Enkapsulasi**: Setiap fungsi menyembunyikan detail implementasi

- **Reusabilitas**: Fungsi dapat digunakan kembali di berbagai bagian

- **Kemandirian**: Fungsi bekerja secara independen tanpa efek samping

- **Interface Jelas**: Input-output terdefinisi dengan baik

#### 2. Manfaat Modularitas


```mermaid

graph LR

A[Kode Spagetti] --> B[Kode Modular]

B --> C[Lebih Mudah Dibaca]

B --> D[Lebih Mudah Diperbaiki]

B --> E[Reusable Components]

B --> F[Testing Lebih Mudah]

```

#### 3. Teknik Implementasi

a. **Decomposition**

Memecah masalah besar menjadi fungsi-fungsi kecil:

```python

# Tanpa modularitas

def proses_data_siswa():

# 100 baris kode kompleks

pass

# Dengan modularitas

def baca_data():

pass

def validasi_data():

pass

def simpan_database():

pass

```
b. **Abstraction**

Menyembunyikan kompleksitas:

```python

# Pengguna cukup tahu ini

nilai_akhir = hitung_nilai_akhir(tugas, uts, uas)

# Tidak perlu tahu detail perhitungan

def hitung_nilai_akhir(tugas, uts, uas):

return tugas*0.3 + uts*0.3 + uas*0.4

```

c. **Komposisi**

Menggabungkan fungsi-fungsi kecil:

```python

def laporan_siswa(nis):

data = ambil_data(nis)

if validasi(data):

return format_laporan(data)

return "Data tidak valid"

```

#### 4. Contoh Sistem Sekolah Modular

```python

# Modul [Link]

def koneksi_db():

"""Koneksi ke database"""

pass

def simpan_siswa(nama, kelas):


pass

# Modul [Link]

def hitung_rata(nilai):

return sum(nilai) / len(nilai)

def konversi_ke_huruf(nilai):

if nilai >= 90: return 'A'

# ...

# Modul [Link]

from database import simpan_siswa

from perhitungan import hitung_rata, konversi_ke_huruf

def proses_nilai_siswa(nama, nilai):

rata = hitung_rata(nilai)

huruf = konversi_ke_huruf(rata)

simpan_siswa(nama, huruf)

return f"{nama}: {huruf}"

# Penggunaan

print(proses_nilai_siswa("Budi", [85, 90, 78]))

```

#### 5. Best Practices Modularitas

1. **Single Responsibility Principle**

Setiap fungsi hanya melakukan satu tugas

2. **Pure Functions**
Fungsi tanpa efek samping:

```python

# Baik: fungsi murni

def tambah(a, b):

return a + b

# Buruk: efek samping

total = 0

def tambah_global(a):

global total

total += a

```

3. **Parameter Explicit**

Hindari ketergantungan global:

```python

# Buruk

KONSTANTA = 10

def kali(a):

return a * KONSTANTA

# Baik

def kali(a, pengali=10):

return a * pengali

```

4. **Documentation**

Gunakan docstring untuk antarmuka:

```python
def hitung_median(data):

"""

Menghitung median dari list angka

Args:

data (list): List nilai numerik

Returns:

float: Nilai median

Raises:

ValueError: Jika data kosong

"""

if not data:

raise ValueError("Data tidak boleh kosong")

# ...implementasi...

```

5. **Maksimal 3 Parameter**

Gunakan struktur data jika perlu banyak parameter:

```python

# Buruk

def daftar_siswa(nama1, nama2, nama3, kelas1, kelas2, kelas3):

pass

# Baik

def daftar_siswa(siswa):

"""siswa: list of tuple [(nama, kelas), ...]"""

pass
```

### Perbandingan: Non-Modular vs Modular

| Aspek | Non-Modular | Modular |

|--------------------|------------------------------|-----------------------------|

| **Panjang Kode** | Satu file ribuan baris | Beberapa file/fungsi kecil


|

| **Maintainability**| Sulit diperbaiki | Perbaikan terisolasi |

| **Reusability** | Copy-paste kode | Import fungsi |

| **Testing** | Hanya tes end-to-end | Unit test per fungsi |

| **Kolaborasi** | Konflik git sering | Bekerja pada modul berbeda


|

Modularitas adalah fondasi pengembangan perangkat lunak profesional.


Dalam konteks aplikasi sekolah Anda, modularitas memungkinkan:

- Pembagian kerja tim (satu orang di UI, satu di database)

- Penggunaan kembali modul perhitungan nilai

- Update fitur tanpa mengganggu sistem keseluruhan

- Unit testing untuk logika kritis seperti perhitungan nilai akhir

- **`*args` & `**kwargs`**

### **`*args` dan `**kwargs`**: Fleksibilitas Parameter Fungsi di Python

#### 🧩 **`*args` (Arbitrary Positional Arguments)**

- **Fungsi**: Menerima **sejumlah variabel argumen posisi**

- **Bentuk**: Tuple yang berisi semua argumen tambahan

- **Kegunaan**: Saat jumlah argumen tidak pasti

**Contoh Tanpa `*args`** (Masalah):

```python
def hitung_total(a, b):

return a + b

print(hitung_total(5, 3)) # Output: 8

print(hitung_total(5, 3, 7)) # Error: hitung_total() takes 2 positional


arguments but 3 were given

```

**Solusi dengan `*args`**:

```python

def hitung_total(*args):

print(f"Tipe args: {type(args)}") # <class 'tuple'>

return sum(args)

print(hitung_total(5, 3)) # Output: 8

print(hitung_total(5, 3, 7)) # Output: 15

print(hitung_total(1, 2, 3, 4)) # Output: 10

```

#### 🔍 Kasus Nyata `*args`:

```python

def nilai_rata(*nilai_siswa):

return sum(nilai_siswa) / len(nilai_siswa) if nilai_siswa else 0

print(nilai_rata(85, 90, 78)) # Output: 84.333...

```

---
#### 🧩 **`**kwargs` (Arbitrary Keyword Arguments)**

- **Fungsi**: Menerima **sejumlah argumen keyword** (nama=value)

- **Bentuk**: Dictionary yang berisi pasangan key-value

- **Kegunaan**: Saat parameter bernama tidak pasti

**Contoh Tanpa `**kwargs`** (Masalah):

```python

def profil_siswa(nama, kelas):

print(f"Nama: {nama}, Kelas: {kelas}")

profil_siswa("Budi", "12 IPA")

# Output: Nama: Budi, Kelas: 12 IPA

profil_siswa("Ani", "11 IPS", ekstra="Pramuka")

# Error: profil_siswa() got an unexpected keyword argument 'ekstra'

```

**Solusi dengan `**kwargs`**:

```python

def profil_siswa(nama, kelas, **kwargs):

print(f"Nama: {nama}, Kelas: {kelas}")

print("Informasi tambahan:")

for key, value in [Link]():

print(f"- {[Link]('_', ' ').title()}: {value}")

profil_siswa("Budi", "12 IPA")

# Output:

# Nama: Budi, Kelas: 12 IPA

# Informasi tambahan:
profil_siswa("Ani", "11 IPS", ekstra="Pramuka", alamat="Jl. Merdeka 123")

# Output:

# Nama: Ani, Kelas: 11 IPS

# Informasi tambahan:

# - Ekstra: Pramuka

# - Alamat: Jl. Merdeka 123

```

#### 🔍 Kasus Nyata `**kwargs`:

```python

def buat_sertifikat(nama, **options):

template = f"""

==============================

SERTIFIKAT PENGHARGAAN

Diberikan kepada: {nama}

Atas prestasi dalam bidang: {[Link]('bidang', 'Umum')}

Tingkat: {[Link]('tingkat', 'Sekolah')}

Tanggal: {[Link]('tanggal', '1 Januari 2024')}

==============================

"""

return template

print(buat_sertifikat("Cici"))

print(buat_sertifikat("Dodi", bidang="Robotik", tingkat="Nasional",


tanggal="15 Maret 2024"))

```
---

### 💡 **Kombinasi `*args` dan `**kwargs`**

```python

def catat_absensi(hari, *siswa_hadir, **catatan_guru):

print(f"\nAbsensi {hari}:")

print("- Siswa hadir:", ", ".join(siswa_hadir))

if catatan_guru:

print("\nCatatan guru:")

for key, val in catatan_guru.items():

print(f"- {key}: {val}")

catat_absensi("Senin", "Budi", "Ani", "Cici")

"""

Absensi Senin:

- Siswa hadir: Budi, Ani, Cici

"""

catat_absensi(

"Rabu",

"Dodi", "Eva",

terlambat="Budi (15 menit)",

izin="Ani (sakit)"

"""

Absensi Rabu:

- Siswa hadir: Dodi, Eva


Catatan guru:

- terlambat: Budi (15 menit)

- izin: Ani (sakit)

"""

```

---

### 📜 **Aturan Urutan Parameter**

Urutan resmi dalam deklarasi fungsi:

```python

def fungsi_valid(a, b=1, *args, c=2, **kwargs):

# 1. Positional: a

# 2. Default: b=1

# 3. *args

# 4. Keyword-only: c=2 (setelah *args)

# 5. **kwargs

pass

```

**Contoh Error Urutan**:

```python

def salah(*args, **kwargs, a):

pass

# SyntaxError: invalid syntax

```

**Contoh Benar**:

```python
def proses_data(kelas, *nilai, guru="Pak Andi", **metadata):

print(f"Kelas: {kelas}")

print(f"Guru: {guru}")

print(f"Nilai: {nilai}")

print(f"Metadata: {metadata}")

proses_data(

"9A",

85, 90, 78,

guru="Bu Siti",

semester=1,

kurikulum="Merdeka"

"""

Kelas: 9A

Guru: Bu Siti

Nilai: (85, 90, 78)

Metadata: {'semester': 1, 'kurikulum': 'Merdeka'}

"""

```

---

### **Teknik Unpacking**

Anda bisa menggunakan `*` dan `**` saat pemanggilan fungsi juga:

```python

def tampilkan_info(nama, kelas, nilai):

print(f"{nama} (Kelas {kelas}): Nilai {nilai}")


# Data dalam struktur

data_siswa = ("Budi", "10 IPA", 85)

data_mapel = {"nama": "Matematika", "kelas": "X", "nilai": 90}

# Unpacking saat pemanggilan

tampilkan_info(*data_siswa) # Output: Budi (Kelas 10 IPA): Nilai 85

tampilkan_info(**data_mapel) # Output: Matematika (Kelas X): Nilai 90

```

---

### 💎 **Kesimpulan**

| Fitur | `*args` | `**kwargs` |

|---------------|----------------------------------|----------------------------------|

| **Jenis** | Positional arguments | Keyword arguments


|

| **Tipe Data** | Tuple | Dictionary |

| **Simbol** | `*` (bintang satu) | `**` (bintang dua) |

| **Use Case** | Jumlah argumen posisi tak pasti | Jumlah argumen


keyword tak pasti |

| **Contoh** | `func(1, 2, 3)` | `func(a=1, b=2)` |

**Best Practices**:

1. Gunakan nama `args`/`kwargs` sebagai konvensi standar

2. Kombinasikan dengan parameter reguler untuk fleksibilitas maksimal

3. Dokumentasikan fungsi dengan jelas jika menggunakan fitur ini

4. Hindari untuk fungsi sederhana dengan parameter tetap

- **Lambda, `filter()`, `map()`, `reduce()`**


### Fungsi Lambda, `filter()`, `map()`, dan `reduce()` dalam Python

Keempat fungsi ini merupakan alat penting dalam **pemrograman


fungsional** Python untuk manipulasi data secara efisien. Mari kita bahas
satu per satu:

---

#### 1. **Fungsi Lambda**

Fungsi anonim sederhana yang didefinisikan dalam satu baris.

**Sintaks**: `lambda arguments: expression`

**Ciri Khusus**:

- Tidak punya nama

- Hanya boleh berisi satu ekspresi

- Tidak mendukung pernyataan (statements)

**Contoh**:

```python

# Fungsi kuadrat

kuadrat = lambda x: x**2

print(kuadrat(5)) # Output: 25

# Fungsi penjumlahan

tambah = lambda a, b: a + b

print(tambah(10, 7)) # Output: 17

```

---

#### 2. **Fungsi `filter()`**


Menyaring elemen dari iterable berdasarkan kondisi.

**Sintaks**: `filter(function, iterable)`

**Cara Kerja**:

- Mengembalikan iterator berisi elemen yang memenuhi kondisi

- Jika function `None`, menyaring elemen yang bernilai `True`

**Contoh** (Filter nilai di atas 70):

```python

nilai = [85, 55, 90, 65, 78, 92]

# Cara 1: Pakai fungsi biasa

def lulus(n):

return n >= 70

print(list(filter(lulus, nilai))) # Output: [85, 90, 78, 92]

# Cara 2: Pakai lambda (lebih ringkas)

print(list(filter(lambda n: n >= 70, nilai))) # Output: [85, 90, 78, 92]

```

---

#### 3. **Fungsi `map()`**

Menerapkan fungsi ke setiap elemen iterable.

**Sintaks**: `map(function, iterable)`

**Ciri**:

- Hasil jumlah elemen sama dengan input

- Bisa menerima banyak iterable


**Contoh** (Konversi nilai ke huruf):

```python

nilai_angka = [85, 92, 78, 65]

# Fungsi konversi

def ke_huruf(n):

if n >= 90: return 'A'

elif n >= 80: return 'B'

elif n >= 70: return 'C'

else: return 'D'

print(list(map(ke_huruf, nilai_angka))) # Output: ['B', 'A', 'C', 'D']

# Pakai lambda + map

print(list(map(lambda n: 'A' if n>=90 else 'B' if n>=80 else 'C' if n>=70


else 'D', nilai_angka)))

```

---

#### 4. **Fungsi `reduce()`**

Menggabungkan elemen iterable menjadi satu nilai menggunakan fungsi


kumulatif.

**Sintaks**: `reduce(function, iterable[, initial])`

**Catatan**:

- Harus diimpor dari `functools`

- Fungsi harus menerima **dua argumen**

**Contoh** (Total nilai siswa):

```python
from functools import reduce

nilai_siswa = [80, 85, 90, 75]

# Cara manual

total = 0

for n in nilai_siswa:

total += n

# Pakai reduce

total_reduce = reduce(lambda a, b: a + b, nilai_siswa)

print(total_reduce) # Output: 330

# Dengan nilai awal

total_plus = reduce(lambda a, b: a + b, nilai_siswa, 100)

print(total_plus) # Output: 430 (330 + 100)

```

---

### 💡 Kombinasi Power: Lambda + Filter + Map + Reduce

**Contoh**: Hitung rata-rata nilai siswa yang lulus (≥70)

```python

from functools import reduce

data_nilai = [65, 85, 55, 90, 70, 60, 78]

# Langkah 1: Filter yang lulus

lulus = filter(lambda n: n >= 70, data_nilai) # [85, 90, 70, 78]


# Langkah 2: Hitung total nilai lulus

total = reduce(lambda a, b: a + b, lulus) # 85+90+70+78 = 323

# Langkah 3: Hitung jumlah siswa lulus

jumlah = len(list(filter(lambda n: n >= 70, data_nilai))) # 4

# Langkah 4: Hitung rata-rata

rata_lulus = total / jumlah

print(f"Rata-rata nilai lulus: {rata_lulus}") # Output: 80.75

```

**Versi Single-Line**:

```python

rata = reduce(lambda a,b: a+b, filter(lambda n: n>=70, data_nilai)) /


len(list(filter(lambda n: n>=70, data_nilai)))

```

---

### 🆚 Perbandingan Fungsi

| Fungsi | Input | Output | Tipe Return | Use Case


|

|-------------|----------------|----------------|---------------|---------------------------|

| **Lambda** | Arguments | Ekspresi | Function | Fungsi


sederhana 1-baris |

| **filter()**| Fungsi + Iterable | Elemen yang lolos | Iterator |


Penyaringan data |

| **map()** | Fungsi + Iterable | Hasil transformasi | Iterator |


Transformasi data |
| **reduce()**| Fungsi + Iterable | Nilai tunggal | Object | Agregasi
data |

---

### 🚫 Batasan & Peringatan

1. **Lambda**:

- Tidak bisa berisi pernyataan kompleks (`if-elif-else`, loop)

- Sulit dibaca jika terlalu panjang

2. **`reduce()`**:

- Tidak selalu intuitif untuk pemula

- Alternatif: Gunakan `sum()`, `max()`, `min()` untuk kasus sederhana

```python

# Lebih baik pakai:

total = sum(data_nilai)

# Daripada:

total = reduce(lambda a,b: a+b, data_nilai)

```

3. **Lazy Evaluation**:

Hasil `filter()` dan `map()` adalah iterator, perlu diubah ke list untuk
penggunaan berulang:

```python

hasil_filter = filter(lambda x: x>10, data)

print(list(hasil_filter)) # Pertama: [11, 12]

print(list(hasil_filter)) # Kedua: [] (iterator sudah habis)

```
---

### 💎 Best Practices

1. Gunakan untuk operasi data **1-2 tahap**

2. Untuk pipeline kompleks, pertimbangkan **comprehension**:

```python

# Daripada map+filter

hasil = [x*2 for x in data if x > 10]

# Daripada reduce

total = sum(x for x in data if x > 10)

```

3. Beri nama jelas untuk fungsi kompleks

4. Dokumentasikan operasi yang tidak jelas

### 🔄 Alternatif Modern (Python 3.8+)

Gunakan **assignment expression** (walrus operator) dengan


comprehension:

```python

# Hitung rata-rata nilai di atas 70

data = [65, 85, 90, 60, 78]

lulus = [n for n in data if n >= 70]

rata = sum(lulus) / len(lulus) if lulus else 0

# Pakai walrus operator (single-line)

rata = (sum(lulus := [n for n in data if n >= 70]) / len(lulus)) if lulus else 0

```

Alat-alat ini adalah senjata ampuh untuk pemrosesan data yang efisien
dan elegan di Python! 🐍
-----------------------------------------------------------------------

#### **6. Pemrograman Berorientasi Objek (OOP)**

- **Kelas & Objek (Classes & Objects)**

### Kelas (Class) dan Objek (Object) dalam OOP Python

#### 🧱 **1. Kelas (Class)**

**Definisi**: Blueprint/template untuk membuat objek. Mendefinisikan


atribut (data) dan metode (perilaku) yang akan dimiliki oleh objek.

**Analogi**:

- Kelas = Cetakan kue 🍪

- Objek = Kue yang dihasilkan dari cetakan

**Sintaks Dasar**:

```python

class NamaKelas:

def __init__(self, parameter): # Constructor

[Link] = parameter # Inisialisasi atribut

def metode(self): # Metode

# Perilaku objek

```

#### 📦 **2. Objek (Object)**

**Definisi**: Instance konkret yang dibuat dari kelas. Memiliki state


(keadaan saat ini) dan behavior (perilaku).

**Analogi**:
- Kelas `Mobil` → Objek `mobil_toyota`, `mobil_honda`

---

### 💡 4 Pilar OOP di Python

#### 1. **Enkapsulasi (Encapsulation)**

Membungkus data dan metode dalam satu unit, mengontrol akses


melalui:

- **Public**: `atribut` (bisa diakses di mana saja)

- **Protected**: `_atribut` (konvensi, akses terbatas)

- **Private**: `__atribut` (hanya bisa diakses di dalam kelas)

```python

class Siswa:

def __init__(self, nama, nis):

[Link] = nama # Public

self._nis = nis # Protected (konvensi)

self.__rahasia = "123" # Private

def tampilkan_data(self):

print(f"Nama: {[Link]}, NIS: {self._nis}")

# Penggunaan

s = Siswa("Budi", "NIS123")

print([Link]) # OK: Budi

print(s._nis) # Warning (tidak disarankan)

# print(s.__rahasia) # Error: AttributeError

```
#### 2. **Pewarisan (Inheritance)**

Kelas anak mewarisi properti dan metode dari kelas induk.

```python

class Person:

def __init__(self, nama, umur):

[Link] = nama

[Link] = umur

def perkenalan(self):

print(f"Saya {[Link]}, {[Link]} tahun")

class Siswa(Person): # Inherit dari Person

def __init__(self, nama, umur, nis):

super().__init__(nama, umur) # Panggil constructor parent

[Link] = nis

def belajar(self):

print(f"{[Link]} sedang belajar")

# Penggunaan

siswa = Siswa("Ani", 17, "NIS456")

[Link]() # Output: Saya Ani, 17 tahun

[Link]() # Output: Ani sedang belajar

```

#### 3. **Polimorfisme (Polymorphism)**

Objek berbeda merespons metode yang sama dengan cara berbeda.


```python

class Guru:

def mengajar(self):

print("Mengajar mata pelajaran")

class Siswa:

def belajar(self):

print("Mendengarkan penjelasan")

def aktivitas_kelas(obj):

[Link]() # Polimorfisme

# Penggunaan

guru = Guru()

siswa = Siswa()

aktivitas_kelas(guru) # Output: Mengajar mata pelajaran

aktivitas_kelas(siswa) # Output: Mendengarkan penjelasan

```

#### 4. **Abstraksi (Abstraction)**

Menyembunyikan detail kompleks, hanya menampilkan fungsionalitas


esensial.

```python

from abc import ABC, abstractmethod

class NilaiOperator(ABC):

@abstractmethod
def hitung_nilai(self):

pass

class NilaiAkhir(NilaiOperator):

def hitung_nilai(self, tugas, uts, uas):

return tugas*0.3 + uts*0.3 + uas*0.4

# Penggunaan

nilai = NilaiAkhir()

print(nilai.hitung_nilai(80, 75, 85)) # Output: 80.5

```

---

### 🏫 Contoh Lengkap: Sistem Sekolah

```python

class MataPelajaran:

def __init__(self, nama, kode):

[Link] = nama

[Link] = kode

def info(self):

return f"{[Link]}: {[Link]}"

class Guru:

def __init__(self, nama, nip):

[Link] = nama

[Link] = nip

self.mapel_diajar = []
def tambah_mapel(self, mapel):

self.mapel_diajar.append(mapel)

def info(self):

mapel_info = ", ".join([[Link] for m in self.mapel_diajar])

return f"Guru {[Link]} (NIP: {[Link]}) - Mengajar: {mapel_info}"

class Siswa:

def __init__(self, nama, nis, kelas):

[Link] = nama

[Link] = nis

[Link] = kelas

[Link] = {}

def tambah_nilai(self, mapel, nilai):

[Link][mapel] = nilai

def raport(self):

print(f"\nRAPORT {[Link]} (Kelas {[Link]})")

for mapel, nilai in [Link]():

print(f"- {[Link]}: {nilai}")

# Penggunaan

matematika = MataPelajaran("Matematika", "MTK")

fisika = MataPelajaran("Fisika", "FIS")

guru1 = Guru("Pak Andi", "GUR001")

guru1.tambah_mapel(matematika)
guru1.tambah_mapel(fisika)

siswa1 = Siswa("Budi", "SIS202", "12 IPA")

siswa1.tambah_nilai(matematika, 85)

siswa1.tambah_nilai(fisika, 78)

print([Link]())

# Output: Guru Pak Andi (NIP: GUR001) - Mengajar: Matematika, Fisika

[Link]()

"""

Output:

RAPORT Budi (Kelas 12 IPA)

- Matematika: 85

- Fisika: 78

"""

```

---

### 🔑 **Konsep Penting Lain**

1. **Constructor (`__init__`)**

Metode khusus yang dipanggil saat objek dibuat.

2. **`self` Parameter**

Merujuk pada instance objek saat ini.

3. **Class vs Instance Attributes**

```python
class Contoh:

atribut_kelas = "Ini milik kelas" # Shared by all instances

def __init__(self, nilai):

self.atribut_instance = nilai # Unique per instance

```

4. **Static Method & Class Method**

```python

class Kalkulator:

@staticmethod

def tambah(a, b):

return a + b

@classmethod

def info(cls):

return f"Ini kelas {cls.__name__}"

```

---

### 💎 **Kesimpulan**

| Konsep | Kelas (Class) | Objek (Object)


|

|----------------|------------------------------------------|------------------------------------|

| **Definisi** | Blueprint/cetakan | Instance nyata dari


kelas |

| **Analogi** | Resep kue | Kue yang sudah jadi


|
| **Deklarasi** | `class NamaKelas:` | `obj = NamaKelas()`
|

| **Komponen** | Atribut, Metode, Constructor | State (nilai


atribut), Behavior |

| **Keunikan** | Satu untuk banyak objek | Unik (memiliki


state sendiri) |

**Manfaat OOP**:

- Modularitas kode

- Reusability tinggi

- Mudah dimaintain

- Modeling sistem dunia nyata lebih intuitif

Dengan OOP, sistem kompleks seperti aplikasi sekolah Anda bisa


diorganisasikan menjadi objek-objek seperti `Siswa`, `Guru`,
`MataPelajaran`, `Jadwal`, dll., yang berinteraksi secara terstruktur.

- **Pewarisan (Inheritance)**:

- Multi-level

### Pewarisan Multi-level dalam OOP Python

Pewarisan multi-level (multi-level inheritance) adalah konsep di mana


sebuah kelas diturunkan dari kelas yang sudah merupakan kelas turunan
(subclass) dari kelas lain. Ini membentuk **rantai pewarisan** dengan
hubungan seperti: Kakek → Ayah → Anak.

#### 🧬 Struktur Hierarki:

```mermaid

graph BT

A[Kelas Kakek] --> B[Kelas Ayah]

B --> C[Kelas Anak]

```
#### 💡 Karakteristik:

1. **Rantai Pewarisan**:

- Kelas Anak mewarisi dari Kelas Ayah

- Kelas Ayah mewarisi dari Kelas Kakek

- Kelas Anak mewarisi sifat Kelas Kakek dan Ayah

2. **Depth Tak Terbatas**:

Bisa memiliki banyak level:

```mermaid

graph BT

A --> B

B --> C

C --> D

D --> E[Level ke-4]

```

---

### 🏫 Contoh Konkret: Sistem Sekolah

```python

# Level 1: Kelas Dasar (Kakek)

class Person:

def __init__(self, nama, umur):

[Link] = nama

[Link] = umur

def perkenalan(self):

print(f"Nama: {[Link]}, Umur: {[Link]} tahun")


# Level 2: Kelas Turunan Pertama (Ayah)

class Siswa(Person):

def __init__(self, nama, umur, nis):

super().__init__(nama, umur)

[Link] = nis

def belajar(self, mapel):

print(f"{[Link]} sedang belajar {mapel}")

# Level 3: Kelas Turunan Kedua (Anak)

class SiswaSMA(Siswa):

def __init__(self, nama, umur, nis, jurusan):

super().__init__(nama, umur, nis)

[Link] = jurusan

def pilih_jurusan(self):

print(f"{[Link]} memilih jurusan {[Link]}")

# Penggunaan

siswa1 = SiswaSMA("Budi", 17, "NIS123", "IPA")

[Link]() # Warisan dari Person

# Output: Nama: Budi, Umur: 17 tahun

[Link]("Matematika") # Warisan dari Siswa

# Output: Budi sedang belajar Matematika

siswa1.pilih_jurusan() # Method sendiri

# Output: Budi memilih jurusan IPA


```

---

### 🔍 Mekanisme Pencarian Method (MRO)

Python menggunakan algoritma **C3 Linearization** untuk menentukan


urutan pencarian method. Bisa dicek dengan `__mro__`:

```python

print(SiswaSMA.__mro__)

# Output: (<class '__main__.SiswaSMA'>, <class '__main__.Siswa'>,


<class '__main__.Person'>, <class 'object'>)

```

Urutan eksekusi:

1. Cek di `SiswaSMA`

2. Jika tidak ada, cek di `Siswa`

3. Jika tidak ada, cek di `Person`

4. Terakhir cek di `object` (base class Python)

---

### ⚠️Potensi Masalah & Solusi

#### 1. **Konflik Nama Method**

```python

class A:

def info(self):

print("Info dari A")

class B(A):
def info(self):

print("Info dari B")

class C(B):

def info(self):

super().info() # Akan memanggil [Link]()

print("Info dari C")

obj = C()

[Link]()

"""

Output:

Info dari B

Info dari C

"""

```

#### 2. **Diamond Problem (Python Tangani Otomatis)**

```mermaid

graph BT

A --> B

A --> C

B --> D

C --> D

```

Python akan mengurutkan secara linier:

```python

class A:
def info(self):

print("A")

class B(A):

def info(self):

print("B")

class C(A):

def info(self):

print("C")

class D(B, C):

pass

print(D.__mro__)

# Output: (<class '__main__.D'>, <class '__main__.B'>, <class


'__main__.C'>, <class '__main__.A'>, <class 'object'>)

d = D()

[Link]() # Output: B (karena B didahulukan dalam MRO)

```

---

### 💡 Best Practices

1. **Gunakan `super()` untuk Akses Parent Class**

```python

class SiswaSMA(Siswa):

def __init__(self, nama, umur, nis, jurusan):


super().__init__(nama, umur, nis) # Panggil constructor parent

[Link] = jurusan

```

2. **Hindari Rantai Terlalu Panjang**

- Max 3-4 level (Kakek → Ayah → Anak → Cucu)

- Rantai panjang menyulitkan maintenance

3. **Gunakan Komposisi Bila Perlu**

Untuk hubungan "has-a" bukan "is-a":

```python

# Daripada multi-level inheritance

class Kelas:

def __init__(self, nama_kelas):

[Link] = nama_kelas

[Link] = [] # Komposisi: Kelas memiliki siswa

def tambah_siswa(self, siswa):

[Link](siswa)

```

4. **Dokumentasikan Hierarki**

Gunakan docstring untuk penjelasan:

```python

class SiswaSMA(Siswa):

"""Mewakili siswa SMA, turunan dari Siswa

Attributes:

jurusan (str): Jurusan siswa (IPA/IPS/Bahasa)


"""

```

---

### 🆚 Perbandingan Jenis Pewarisan

| Jenis | Contoh | Use Case |

|---------------------|-------------------------|-----------------------------------|

| **Single** |A→B | Hubungan dasar parent-child |

| **Multi-level** |A→B→C | Spesialisasi bertahap |

| **Hierarchical** | A → B, A → C | Satu parent punya banyak child


|

| **Multiple** | B ← A → C (D turunannya)| Gabungkan fitur dari


beberapa kelas |

---

### 💎 Kesimpulan

Pewarisan multi-level cocok untuk:

- Modeling sistem dengan hierarki alami (Sekolah: Person → Siswa →


SiswaSMA)

- Spesialisasi bertahap di mana setiap level menambahkan fungsionalitas


baru

- Mengurangi duplikasi kode melalui warisan bertingkat

Dengan contoh sekolah:

- `Person`: Fungsi dasar manusia

- `Siswa`: Tambahan properti sekolah

- `SiswaSMA`: Spesialisasi untuk jenjang SMA


```python

siswa = SiswaSMA("Diana", 16, "SMA202", "IPS")

[Link]() # Dari Person

[Link]("Ekonomi") # Dari Siswa

siswa.pilih_jurusan() # Spesifik SiswaSMA

```

Hasil:

```

Nama: Diana, Umur: 16 tahun

Diana sedang belajar Ekonomi

Diana memilih jurusan IPS

```

- Multiple

### Pewarisan Multiple dalam OOP Python

Pewarisan multiple (multiple inheritance) adalah konsep di mana sebuah


kelas **mewarisi dari dua atau lebih kelas induk** sekaligus. Ini
memungkinkan kelas anak menggabungkan atribut dan metode dari
beberapa kelas induk.

#### 🧬 Struktur Dasar:

```python

class KelasInduk1:

# Atribut dan metode

class KelasInduk2:

# Atribut dan metode


class KelasAnak(KelasInduk1, KelasInduk2):

# Mewarisi dari kedua induk

```

#### 💡 Contoh Praktis: Sistem Sekolah

```python

class Akademik:

def __init__(self, nilai):

[Link] = nilai

def cetak_raport(self):

print(f"Nilai akademik: {[Link]}")

class Ekstrakurikuler:

def __init__(self, kegiatan):

[Link] = kegiatan

def cetak_sertifikat(self):

print(f"Kegiatan ekstrakurikuler: {[Link]}")

# Kelas yang mewarisi dari dua kelas induk

class Siswa(Akademik, Ekstrakurikuler):

def __init__(self, nama, nilai, kegiatan):

# Inisialisasi kedua induk

Akademik.__init__(self, nilai)

Ekstrakurikuler.__init__(self, kegiatan)

[Link] = nama

def profil_lengkap(self):
print(f"\nProfil Siswa: {[Link]}")

self.cetak_raport()

self.cetak_sertifikat()

# Penggunaan

siswa1 = Siswa("Budi", 85, "Pramuka")

siswa1.profil_lengkap()

"""

Output:

Profil Siswa: Budi

Nilai akademik: 85

Kegiatan ekstrakurikuler: Pramuka

"""

```

---

### 🔍 Mekanisme MRO (Method Resolution Order)

Python menggunakan algoritma C3 Linearization untuk menentukan


urutan pencarian method. Urutan bisa dilihat dengan `__mro__`:

```python

print(Siswa.__mro__)

# Output: (<class '__main__.Siswa'>, <class '__main__.Akademik'>,


<class '__main__.Ekstrakurikuler'>, <class 'object'>)

```

Aturan pencarian:

1. Cek di kelas anak (`Siswa`)

2. Cek di induk pertama (`Akademik`)


3. Cek di induk kedua (`Ekstrakurikuler`)

4. Cek di base class (`object`)

---

### 💡 Contoh Lebih Kompleks: Diamond Problem

```mermaid

graph BT

A[Person] --> B[Guru]

A --> C[Siswa]

B --> D[AsistenLab]

C --> D

```

Implementasi:

```python

class Person:

def perkenalan(self):

print("Saya adalah person")

class Guru(Person):

def perkenalan(self):

print("Saya seorang guru")

class Siswa(Person):

def perkenalan(self):

print("Saya seorang siswa")

class AsistenLab(Guru, Siswa):


pass

# Penggunaan

asisten = AsistenLab()

[Link]() # Output: Saya seorang guru

print(AsistenLab.__mro__)

# Output: (<class '__main__.AsistenLab'>, <class '__main__.Guru'>,


<class '__main__.Siswa'>, <class '__main__.Person'>, <class 'object'>)

```

---

### Teknik Penting

#### 1. Menggunakan `super()` dengan Multiple Inheritance

```python

class A:

def __init__(self):

print("A")

super().__init__()

class B:

def __init__(self):

print("B")

super().__init__()

class C(A, B):

def __init__(self):

print("C")

super().__init__()
obj = C()

"""

Output:

"""

```

#### 2. Memanggil Method Spesifik Induk

```python

class Siswa(Akademik, Ekstrakurikuler):

def __init__(self, nama, nilai, kegiatan):

# Panggil constructor spesifik

Akademik.__init__(self, nilai)

Ekstrakurikuler.__init__(self, kegiatan)

[Link] = nama

```

---

### ⚠️Potensi Masalah & Solusi

#### 1. Konflik Nama Method

```python

class Induk1:

def metode(self):

print("Dari Induk1")
class Induk2:

def metode(self):

print("Dari Induk2")

class Anak(Induk1, Induk2):

pass

anak = Anak()

[Link]() # Output: Dari Induk1 (karena urutan MRO)

```

**Solusi**:

- Gunakan nama method berbeda

- Override di kelas anak

```python

class Anak(Induk1, Induk2):

def metode(self):

[Link](self) # Panggil spesifik

[Link](self)

print("Dari Anak")

```

#### 2. Constructor Kompleks

**Solusi**: Gunakan teknik cooperative multiple inheritance

```python

class Dasar:

def __init__(self, **kwargs):

super().__init__(**kwargs)
class Akademik(Dasar):

def __init__(self, nilai, **kwargs):

super().__init__(**kwargs)

[Link] = nilai

class Ekstrakurikuler(Dasar):

def __init__(self, kegiatan, **kwargs):

super().__init__(**kwargs)

[Link] = kegiatan

class Siswa(Akademik, Ekstrakurikuler):

def __init__(self, nama, **kwargs):

super().__init__(**kwargs)

[Link] = nama

# Penggunaan

siswa = Siswa(

nama="Ani",

nilai=90,

kegiatan="Robotik"

```

---

### 💡 Best Practices

1. **Gunakan untuk Konsep "Mixins"**

Kelas kecil yang menambahkan fungsionalitas spesifik:

```python
class LoggerMixin:

def log(self, pesan):

print(f"[LOG] {pesan}")

class Siswa(Akademik, LoggerMixin):

def simpan_data(self):

[Link]("Data disimpan")

```

2. **Hindari Deep Hierarchy**

Multiple inheritance bekerja baik untuk 2-3 induk

3. **Dokumentasikan dengan Baik**

```python

class Siswa(Akademik, Ekstrakurikuler):

"""Kelas siswa yang mewarisi sifat akademik dan ekstrakurikuler

MRO:

1. Siswa

2. Akademik

3. Ekstrakurikuler

"""

```

4. **Gunakan Komposisi Bila Ragu**

Jika hubungan "has-a" bukan "is-a":

```python

class Siswa:

def __init__(self, akademik, ekstra):


[Link] = akademik

[Link] = ekstra

```

---

### 🆚 Perbandingan dengan Bahasa Lain

| Fitur | Python | Java/C# |

|--------------------|---------------------------------------|----------------------------------|

| Dukungan | ✅ Ya | ❌ Tidak (interface saja) |

| Diamond Problem | ✅ Ditangani dengan MRO | ❌ Tidak ada


multiple inheritance|

| Fleksibilitas | Tinggi | Terbatas |

| Kompleksitas | Potensi tinggi | Rendah


|

---

### 💎 Kesimpulan

Pewarisan multiple cocok untuk:

1. **Konsep Mixins**: Menambahkan fungsionalitas khusus

```python

class Siswa(Akademik, PencetakRaport, PengirimEmail):

```

2. **Model Konsep Hibrid**:

```python

class AsistenDosen(Guru, Mahasiswa):

```
3. **Kode Reusable**:

```python

class SiswaBaru(Pendaftaran, Pembayaran, Akademik):

```

Contoh sekolah akhir:

```python

class Siswa(Akademik, Ekstrakurikuler, Kehadiran):

def __init__(self, nama):

[Link] = nama

# Inisialisasi lainnya...

siswa = Siswa("Budi")

siswa.cetak_raport() # Dari Akademik

siswa.cetak_sertifikat() # Dari Ekstrakurikuler

siswa.catat_kehadiran() # Dari Kehadiran

```

Dengan pewarisan multiple, Anda bisa membuat objek yang "memiliki


banyak peran" dalam sistem sekolah!

- **Penyampingan Metode (Method Overriding)**

### **Overriding Method** dalam OOP Python

**Overriding method** (penimpaan metode) adalah konsep di mana


sebuah kelas anak mendefinisikan ulang implementasi metode yang
sudah ada di kelas induknya. Ini memungkinkan kelas anak untuk
menyediakan perilaku spesifik yang berbeda dari kelas induk, sambil
mempertahankan nama dan tanda tangan metode yang sama.

---
#### 🧩 Ciri Utama Overriding:

1. **Nama Metode Sama** dengan kelas induk

2. **Parameter Sama** (jumlah dan tipe)

3. **Implementasi Berbeda**

4. **Mekanisme Polimorfisme**

---

### 🏫 Contoh Sederhana: Sistem Sekolah

```python

class Person:

def perkenalan(self):

print("Saya adalah seorang person")

class Guru(Person):

# Overriding method perkenalan

def perkenalan(self):

print("Saya adalah seorang guru")

class Siswa(Person):

# Overriding method perkenalan

def perkenalan(self):

print("Saya adalah seorang siswa")

# Penggunaan

p = Person()

g = Guru()

s = Siswa()
[Link]() # Output: Saya adalah seorang person

[Link]() # Output: Saya adalah seorang guru

[Link]() # Output: Saya adalah seorang siswa

```

---

### 🔧 Teknik Overriding Lanjutan

#### 1. **Menggunakan `super()` untuk Akses Kelas Induk**

```python

class Person:

def __init__(self, nama):

[Link] = nama

class Siswa(Person):

def __init__(self, nama, nis):

super().__init__(nama) # Panggil constructor kelas induk

[Link] = nis

def perkenalan(self):

super().perkenalan() # Panggil metode kelas induk

print(f"Nama: {[Link]}, NIS: {[Link]}")

# Penggunaan

s = Siswa("Budi", "NIS123")

[Link]()

"""
Output:

Saya adalah seorang person

Nama: Budi, NIS: NIS123

"""

```

#### 2. **Partial Overriding**

```python

class Penilaian:

def hitung_nilai(self, tugas, ujian):

return tugas * 0.4 + ujian * 0.6

class PenilaianPraktikum(Penilaian):

def hitung_nilai(self, tugas, ujian, praktikum):

nilai_dasar = super().hitung_nilai(tugas, ujian)

return nilai_dasar * 0.7 + praktikum * 0.3

# Penggunaan

nilai_akhir = PenilaianPraktikum().hitung_nilai(80, 75, 90)

print(f"Nilai akhir: {nilai_akhir:.2f}") # Output: Nilai akhir: 79.10

```

---

### 💡 Perbedaan Overloading vs Overriding

| Karakteristik | Overloading | Overriding |

|---------------------|----------------------------------|--------------------------------|

| **Definisi** | Metode nama sama, parameter beda | Metode nama


dan parameter sama |
| **Tujuan** | Fleksibilitas pemanggilan | Perubahan perilaku
subclass |

| **Dukungan Python** | Tidak langsung (gunakan trik) | Didukung


penuh |

| **Hubungan Kelas** | Dalam kelas sama | Antara kelas induk


dan anak |

---

### 🚫 Batasan dan Solusi

#### 1. **Final Methods** (Python 3.8+)

```python

from typing import final

class Base:

@final

def metode_penting(self):

print("Tidak bisa di-override")

class Anak(Base):

def metode_penting(self): # Error: Cannot override final method

print("Coba override")

```

#### 2. **Abstract Base Classes (ABC)**

```python

from abc import ABC, abstractmethod

class Pembayaran(ABC):
@abstractmethod

def proses_bayar(self, jumlah):

pass

class BayarTunai(Pembayaran):

def proses_bayar(self, jumlah): # Wajib di-override

print(f"Bayar tunai: {jumlah}")

# Penggunaan

BayarTunai().proses_bayar(500000) # Output: Bayar tunai: 500000

```

---

### 💎 Best Practices Overriding

1. **Pertahankan Kontrak**

Jaga kesepakatan input/output metode:

```python

class Induk:

def metode(self, x: int) -> float:

return float(x)

class Anak(Induk):

def metode(self, x: int) -> float: # Tipe sama

return float(x * 2)

```

2. **Dokumentasikan Perubahan**

```python
class SiswaBaru(Siswa):

def perkenalan(self):

"""Override perkenalan dengan versi lebih formal"""

print(f"Perkenalkan, nama saya {[Link]}")

```

3. **Gunakan Decorator `@override` (Python 3.12+)**

```python

from typing import override

class Siswa(Person):

@override

def perkenalan(self):

print("Saya siswa")

```

4. **Hindari Side Effects**

Jangan ubah state objek dengan cara yang tidak terduga:

```python

# Buruk

class AkunBank:

def tarik_tunai(self, jumlah):

[Link] -= jumlah

class AkunSiswa(AkunBank):

def tarik_tunai(self, jumlah):

if jumlah > 100000:

raise ValueError("Melebihi batas siswa")

super().tarik_tunai(jumlah)
```

---

### ⚠️Bahaya Overriding

1. **Liskov Substitution Principle Violation**

Subclass harus bisa menggantikan superclass tanpa mengubah perilaku


program:

```python

# Buruk: Mengubah tipe return

class Induk:

def proses(self) -> int:

return 10

class Anak(Induk):

def proses(self) -> str: # Violation

return "10"

```

2. **Ketergantungan Implementasi**

Hindari asumsi tentang implementasi internal superclass:

```python

# Buruk: Asumsi variabel internal

class Induk:

def __init__(self):

self._data = []

class Anak(Induk):

def tambah_data(self, item):


self._data.append(item) # Bahaya jika _data diubah di superclass

```

---

### 🏁 Kesimpulan

Overriding method adalah teknik penting untuk:

1. **Spesialisasi Perilaku**

Subclass bisa menyediakan implementasi spesifik

```python

class SiswaHonor(Siswa):

def hitung_biaya(self):

return super().hitung_biaya() * 0.8 # Diskon 20%

```

2. **Polimorfisme**

Objek berbeda merespons metode sama dengan cara berbeda

```python

def cetak_perkenalan(obj):

[Link]() # Polimorfik

cetak_perkenalan(Guru()) # Output guru

cetak_perkenalan(Siswa()) # Output siswa

```

3. **Ekstensibilitas**

Tambahkan fungsionalitas tanpa mengubah kode superclass

```python

class SiswaInternasional(Siswa):
def perkenalan(self):

super().perkenalan()

print("Saya dari program pertukaran pelajar")

```

Dengan memahami dan menerapkan overriding dengan baik, Anda bisa


membangun sistem OOP yang fleksibel seperti aplikasi sekolah dengan
hierarki kelas yang jelas dan perilaku yang terprediksi!

-----------------------------------------------------------------------

#### **7. Konsep Lanjutan**

- **Kontainer (Container)**

Dalam Python, **kontainer (container)** adalah struktur data yang


digunakan untuk menyimpan koleksi objek (data) lainnya. Kontainer
bertindak sebagai "wadah" yang mengelompokkan beberapa elemen
secara bersama-sama. Objek-objek yang disimpan bisa beragam tipe data
(integer, string, list, dll.), dan kontainer menyediakan cara untuk
mengakses, mengelola, dan mengiterasi elemen-elemen tersebut.

### Jenis Kontainer Bawaan (Built-in) Python:

Berikut kontainer utama yang tersedia di Python:

1. **`list` (Daftar)**

- **Mutable** (dapat diubah setelah dibuat).

- Urutan elemen **tertata** (ordered).

- Elemen diakses via indeks (contoh: `my_list[0]`).

- Boleh berisi duplikat.

```python

contoh_list = [1, "dua", 3.0, [4, 5]] # Bisa campur tipe data

```
2. **`tuple` (Tupel)**

- **Immutable** (tidak bisa diubah setelah dibuat).

- Urutan elemen **tertata** (ordered).

- Umumnya digunakan untuk data yang tetap (misal: koordinat).

```python

contoh_tuple = (1, "Python", True)

```

3. **`dict` (Kamus/Dictionary)**

- **Mutable**.

- Menyimpan data dalam pasangan **key-value**.

- **Tidak tertata** (unordered) hingga Python 3.6; tertata sejak Python


3.7+.

- Key harus unik dan immutable (string, angka, tuple).

```python

contoh_dict = {"nama": "Budi", "umur": 20, "kota": "Jakarta"}

```

4. **`set` (Himpunan)**

- **Mutable** (juga ada versi immutable-nya: `frozenset`).

- **Tidak tertata** dan **elemen unik** (duplikat otomatis dihapus).

- Berguna untuk operasi himpunan (union, intersection, dll.).

```python

contoh_set = {1, 2, 3, 3, 4} # Hasil: {1, 2, 3, 4}

```

### Karakteristik Umum Kontainer:

- **Mengelompokkan Multi-Elemen**: Menyimpan lebih dari satu objek


sekaligus.
- **Iterable**: Bisa di-loop menggunakan `for` (contoh: `for item in
my_list`).

- **Mendukung Pengecekan Keanggotaan**: Cek elemen dengan `in`


(contoh: `"a" in my_list`).

- **Fleksibel Tipe Data**: Elemen bisa berbeda tipe data dalam satu
kontainer.

### Contoh Operasi Dasar:

```python

# List

buah = ["apel", "mangga", "jeruk"]

[Link]("anggur") # Menambah elemen

# Tuple

koordinat = (4, 5)

x, y = koordinat # Unpacking

# Dictionary

mahasiswa = {"nama": "Diana", "nim": "12345"}

print(mahasiswa["nama"]) # Output: "Diana"

# Set

a = {1, 2, 3}

b = {3, 4, 5}

print([Link](b)) # Output: {3}

```

### Kontainer Lainnya:

- **`collections` Module**: Menyediakan kontainer khusus seperti


`deque`, `Counter`, `namedtuple`, dll.
- **String**: Meskipun menyimpan karakter, string bersifat **immutable**
dan termasuk kontainer sequence.

- **Byte Arrays**: Kontainer mutable untuk data bytes.

### Kesimpulan:

Kontainer adalah inti dari manajemen data di Python. Pemilihan jenis


kontainer tergantung pada kebutuhan:

- Gunakan **`list`** untuk koleksi yang perlu diubah.

- Gunakan **`tuple`** untuk data tetap.

- Gunakan **`dict`** untuk data terlabeli (key-value).

- Gunakan **`set`** untuk elemen unik dan operasi himpunan.

Modul `collections` di Python menyediakan **kontainer khusus


(specialized container datatypes)** yang merupakan alternatif lebih
powerful dari kontainer bawaan Python (seperti `list`, `dict`, `tuple`).
Kontainer ini dirancang untuk menyelesaikan masalah spesifik secara
efisien.

Berikut penjelasan kontainer utama dalam `collections`:

### 1. `namedtuple()`

- **Fungsi**: Membuat tuple dengan nama field.

- **Keunggulan**: Mengakses elemen dengan nama (bukan indeks),


meningkatkan keterbacaan kode.

- **Penggunaan**:

```python

from collections import namedtuple

# Buat struktur 'Point' dengan field x dan y

Point = namedtuple('Point', ['x', 'y'])

p = Point(11, y=22)
print(p.x, p.y) # Output: 11 22

print(p[0] + p[1]) # Output: 33 (tetap bisa akses indeks)

```

### 2. `deque` (Double-Ended Queue)

- **Fungsi**: List yang dioptimalkan untuk operasi cepat di **dua ujung**


(depan/belakang).

- **Keunggulan**: Lebih cepat dari `list` untuk `append`/`pop` di kiri


(`O(1)` vs `O(n)`).

- **Metode Penting**:

- `appendleft()`, `popleft()`

- `extendleft()`, `rotate()`

- **Penggunaan**:

```python

from collections import deque

dq = deque(['a', 'b'])

[Link]('x') # Tambah di kiri: ['x', 'a', 'b']

[Link]() # Hapus di kanan: 'b'

[Link](1) # Rotasi: ['a', 'x'] -> ['x', 'a']

```

### 3. `Counter`

- **Fungsi**: Subkelas `dict` untuk menghitung objek hashable.

- **Keunggulan**: Menghitung frekuensi elemen secara efisien.

- **Metode Penting**:

- `elements()`, `most_common(n)`

- Aritmatika: `+`, `-`, `&` (interseksi), `|` (union)

- **Penggunaan**:
```python

from collections import Counter

cnt = Counter('abracadabra')

print(cnt) # Output: Counter({'a': 5, 'b': 2, 'r': 2, ...})

print(cnt.most_common(2)) # Output: [('a', 5), ('b', 2)]

```

### 4. `OrderedDict`

- **Fungsi**: `dict` yang mengingat urutan penambahan elemen (relevan


di Python <3.7, karena `dict` biasa sekarang sudah ordered).

- **Keunggulan**: Mempertahankan urutan iterasi sesuai insert.

- **Metode Penting**: `move_to_end(key)`, `popitem(last=True)`

- **Penggunaan**:

```python

from collections import OrderedDict

od = OrderedDict()

od['a'] = 1

od['b'] = 2

od.move_to_end('a') # Pindah 'a' ke akhir: {'b': 2, 'a': 1}

```

### 5. `defaultdict`

- **Fungsi**: `dict` yang memanggil fungsi "factory" otomatis saat kunci


tidak ada.

- **Keunggulan**: Menghindari `KeyError` dan menyederhanakan kode.

- **Penggunaan**:

```python

from collections import defaultdict


# Otomatis buat list baru saat kunci baru diakses

dd = defaultdict(list)

dd['fruits'].append('Apple') # Tidak perlu cek kunci eksis

dd['fruits'].append('Mango')

print(dd) # Output: defaultdict(<class 'list'>, {'fruits': ['Apple',


'Mango']})

```

### 6. `ChainMap`

- **Fungsi**: Menggabungkan beberapa dict/mapping menjadi satu view.

- **Keunggulan**: Pencarian berurutan di semua dict (berguna untuk


konfigurasi bertingkat).

- **Penggunaan**:

```python

from collections import ChainMap

dict1 = {'a': 1, 'b': 2}

dict2 = {'b': 3, 'c': 4}

chain = ChainMap(dict1, dict2)

print(chain['a']) # Output: 1 (ambil dari dict1)

print(chain['b']) # Output: 2 (ambil dari dict1, berhenti saat ketemu)

print(chain['c']) # Output: 4 (ambil dari dict2)

```

### 7. `UserDict`, `UserList`, `UserString`

- **Fungsi**: Pembungkus (wrapper) untuk membuat subkelas dari `dict`,


`list`, atau `string` dengan lebih mudah.
- **Keunggulan**: Memodifikasi perilaku kontainer bawaan tanpa
kompleksitas inheritance langsung.

---

### **Kapan Menggunakan `collections`?**

| Kasus Penggunaan | Kontainer yang Cocok |

|-------------------------------|--------------------------|

| Menghitung frekuensi elemen | `Counter` |

| Operasi stack/queue efisien | `deque` |

| Struktur data dengan field | `namedtuple` |

| Dict dengan nilai default | `defaultdict` |

| Menggabungkan konfigurasi | `ChainMap` |

| Butuh urutan insert (Python<3.7)| `OrderedDict` |

Modul `collections` adalah senjata penting untuk optimasi dan penulisan


kode Python yang lebih bersih dan efisien. 💡

- **Iterable & Iterator**

Dalam Python, **iterable** dan **iterator** adalah konsep inti yang


mendukung perulangan (looping) dan proses iterasi. Berikut penjelasan
lengkapnya:

---

### **1. Iterable**

- **Apa itu?**

Objek yang dapat di-**loop** (misal: menggunakan `for`).

Iterable mampu mengembalikan elemennya **satu per satu**.


- **Ciri khas:**

Memiliki metode `__iter__()` yang mengembalikan sebuah **iterator**.

*(Atau mendukung `__getitem__()` untuk akses indeks, seperti


list/tuple)*.

- **Contoh iterable:**

```python

list, tuple, str, dict, set, file, range, generator, dll.

```

- **Cara kerja:**

Saat Anda menulis `for item in obj:`, Python secara otomatis memanggil
`iter(obj)` untuk mendapatkan iterator dari objek tersebut.

- **Contoh penggunaan:**

```python

my_list = [1, 2, 3] # <-- 'my_list' adalah iterable

for num in my_list: # Python panggil iter(my_list) secara implisit

print(num)

```

---

### **2. Iterator**

- **Apa itu?**

Objek yang bertugas **mengelola iterasi** dengan melacak posisi saat


ini selama perulangan.

Iterator bertanggung jawab menghasilkan **nilai berikutnya** dalam


iterasi.
- **Ciri khas:**

1. Memiliki metode `__iter__()` yang mengembalikan dirinya sendiri


(*iterator juga iterable*).

2. Memiliki metode `__next__()` yang:

- Mengembalikan **nilai berikutnya**

- Melemparkan `StopIteration` jika elemen sudah habis.

- **Contoh iterator:**

Hasil dari `iter(iterable)`, generator, objek file, dll.

- **Cara kerja manual:**

```python

my_list = [1, 2, 3]

my_iterator = iter(my_list) # Dapatkan iterator dari iterable

print(next(my_iterator)) # 1

print(next(my_iterator)) # 2

print(next(my_iterator)) # 3

print(next(my_iterator)) # StopIteration (error)

```

---

### **Diagram Hubungan Iterable ↔ Iterator**

```

[Iterable]

│ memiliki metode
▼ __iter__()

[Iterator] ←──────────┐

│ │

│ memiliki metode │ mengembalikan

▼ __next__() │ diri sendiri

[Nilai berikutnya] │

│ │

└─────────────────┘

```

---

### **Perbedaan Kunci**

| Fitur | Iterable | Iterator |

|----------------------|-----------------------------------|-----------------------------------|

| **Metode wajib** | `__iter__()` | `__iter__()` dan


`__next__()` |

| **Status** | Menyimpan data | Melacak posisi iterasi


saat ini |

| **Sifat perulangan** | Bisa diulang berkali-kali | Sering *single-pass*


(habis sekali pakai) |

| **Contoh** | `[1, 2, 3]`, `"hello"` | `iter([1,2,3])`, generator


|

---

### **Contoh Kode: Membuat Iterator Kustom**

```python

class Counter:

def __init__(self, max):


[Link] = max

def __iter__(self):

self.n = 0

return self # Kembalikan iterator (dirinya sendiri)

def __next__(self):

if self.n < [Link]:

self.n += 1

return self.n

raise StopIteration # Tanda iterasi selesai

# Penggunaan:

counter_iter = Counter(3) # Iterator sekaligus iterable

for num in counter_iter:

print(num) # Output: 1, 2, 3

```

---

### **Fakta Penting**

1. **Semua iterator adalah iterable**, tapi tidak sebaliknya.

*Contoh: List adalah iterable, tapi bukan iterator. Hasil `iter(list)` adalah
iterator.*

2. **Iterator sering sekali pakai** (exhausted):

```python

numbers = iter([1, 2, 3])

list(numbers) # [1, 2, 3]
list(numbers) # [] (sudah habis)

```

3. **Perulangan `for` di Python:**

Secara internal diubah menjadi:

```python

iterator = iter(iterable)

while True:

try:

item = next(iterator)

except StopIteration:

break

# Proses item

```

---

### **Kesimpulan**

- **Iterable**: Objek yang bisa di-loop (punya data).

- **Iterator**: Mekanisme yang mengambil nilai satu per satu dari iterable
sambil melacak posisi saat ini.

- Iterasi terjadi ketika Anda memanggil `iter()` pada iterable untuk


mendapatkan iterator, lalu berulang kali memanggil `next()` hingga
`StopIteration`.

Dua konsep ini adalah pondasi dari perulangan, generator, dan banyak
fitur fungsional di Python! 🐍

- **Generator**

### **Generator dalam Python**


**Generator** adalah fungsi khusus yang memungkinkan Anda membuat
iterator dengan cara yang sederhana dan efisien. Berbeda dengan fungsi
biasa yang mengembalikan nilai sekaligus dengan `return`, generator
menggunakan kata kunci `yield` untuk mengembalikan nilai satu per satu
secara bertahap, sambil **mempertahankan status eksekusi** di antara
panggilan.

---

### **Cara Kerja Generator**

1. **Lazy Evaluation (Evaluasi Malas)**:

- Generator tidak menghitung semua nilai sekaligus

- Nilai dihasilkan hanya saat diminta (on-demand)

- Menghemat memori terutama untuk urutan besar/tak terbatas

2. **Mekanisme `yield`**:

- Saat pertama kali dipanggil, fungsi generator mengembalikan objek


generator

- Setiap kali `next()` dipanggil, eksekusi berjalan hingga `yield`

- Status fungsi dibekukan (variabel lokal disimpan)

- Saat `next()` dipanggil lagi, eksekusi dilanjutkan dari titik `yield`


terakhir

---

### **Contoh Dasar**

```python

def simple_generator():

yield 1

yield 2
yield 3

# Membuat objek generator

gen = simple_generator()

print(next(gen)) # Output: 1

print(next(gen)) # Output: 2

print(next(gen)) # Output: 3

print(next(gen)) # StopIteration

```

---

### **Perbedaan Fungsi Biasa vs Generator**

| Karakteristik | Fungsi Biasa | Generator |

|------------------------|-----------------------|------------------------|

| **Kembalian** | `return` (sekali) | `yield` (bertahap) |

| **Status** | Hilang setelah return | Dipertahankan |

| **Tipe kembalian** | Nilai tunggal | Objek generator |

| **Penggunaan memori** | Menyimpan semua hasil | Hanya menyimpan


state |

---

### **Keuntungan Menggunakan Generator**

1. **Efisiensi memori**: Tidak menyimpan seluruh urutan di memori

2. **Bekerja dengan urutan tak terbatas**:

```python

def infinite_sequence():
num = 0

while True:

yield num

num += 1

```

3. **Pipeline data**: Membuat aliran pemrosesan data yang efisien

4. **Kode lebih bersih**: Menggantikan kelas iterator kustom

---

### **Bentuk Generator**

1. **Fungsi Generator**:

```python

def countdown(n):

while n > 0:

yield n

n -= 1

for i in countdown(5):

print(i) # 5, 4, 3, 2, 1

```

2. **Generator Expression** (mirip list comprehension):

```python

# Bentuk list comprehension (menyimpan semua di memori)

squares_list = [x**2 for x in range(1000000)]

# Bentuk generator expression (lazy evaluation)

squares_gen = (x**2 for x in range(1000000))


print(next(squares_gen)) # 0

print(next(squares_gen)) # 1

```

---

### **Contoh Praktis: Membaca File Besar**

```python

def read_large_file(file_path):

with open(file_path, 'r') as file:

for line in file:

yield [Link]()

# Pemrosesan baris per baris tanpa memuat seluruh file

for line in read_large_file('[Link]'):

process(line) # Proses setiap baris satu per satu

```

---

### **Fitur Lanjutan Generator**

1. **Mengirim nilai ke generator**:

```python

def generator_with_send():

value = yield "First"

yield f"Received: {value}"

gen = generator_with_send()
print(next(gen)) # "First"

print([Link]("Hello")) # "Received: Hello"

```

2. **Generator sebagai pipeline**:

```python

def producer():

yield from range(5)

def consumer():

for num in producer():

yield num * 2

print(list(consumer())) # [0, 2, 4, 6, 8]

```

---

### **Kapan Menggunakan Generator?**

1. Saat bekerja dengan aliran data besar/tak terbatas

2. Saat ingin mengimplementasikan iterator kompleks dengan kode


minimal

3. Untuk membangun pipeline pemrosesan data

4. Saat ingin menunda komputasi hingga benar-benar dibutuhkan

Generator adalah jantung dari banyak fitur Python modern seperti:

- Asynchronous programming (`async`/`await`)

- Pemrosesan data besar (library seperti Dask)

- Framework web (FastAPI, Django Channels)


Dengan memahami generator, Anda menguasai salah satu konsep paling
elegan dan powerful di Python! 🐍💡

- **Dekorator (Decorator)**

### **Dekorator (Decorator) dalam Python**

Dekorator adalah **alat yang sangat powerful** dalam Python yang


memungkinkan Anda memodifikasi perilaku fungsi atau kelas tanpa
mengubah kode sumbernya secara permanen. Secara sederhana,
dekorator adalah fungsi yang "membungkus" fungsi lain untuk menambah
fungsionalitas baru.

---

#### **Analog Praktis**

Bayangkan Anda memiliki sebuah hadiah (fungsi asli). Dekorator seperti


**pembungkus kado** yang:

1. Mengambil hadiah tersebut

2. Membungkusnya dengan kertas kado baru (menambah fungsionalitas)

3. Memberikan hadiah yang sudah dibungkus kepada penerima

---

### **Cara Kerja Dasar**

```python

def dekorator_saya(func):

def pembungkus():

print("Sebelum fungsi dieksekusi")

func() # Memanggil fungsi asli

print("Setelah fungsi dieksekusi")


return pembungkus

@dekorator_saya

def sapa():

print("Halo!")

sapa()

```

**Output:**

```

Sebelum fungsi dieksekusi

Halo!

Setelah fungsi dieksekusi

```

---

### **Mengapa Menggunakan Dekorator?**

1. **DRY Principle** (Don't Repeat Yourself):

- Menghindari duplikasi kode untuk fungsionalitas umum

2. **Memisahkan Kekhawatiran**:

- Logika inti vs. logika tambahan (logging, autentikasi, dll)

3. **Ekstensibilitas**:

- Menambah fitur tanpa mengubah kode asli

---

### **Contoh Kasus Nyata**


#### 1. Pengukuran Waktu Eksekusi

```python

import time

def timer(func):

def wrapper(*args, **kwargs):

start = [Link]()

result = func(*args, **kwargs)

end = [Link]()

print(f"{func.__name__} selesai dalam {end - start:.4f} detik")

return result

return wrapper

@timer

def proses_data():

[Link](2)

print("Proses selesai")

proses_data()

```

#### 2. Autentikasi

```python

def login_required(func):

def wrapper(user, *args, **kwargs):

if user.is_authenticated:

return func(user, *args, **kwargs)

else:

raise PermissionError("Anda harus login!")


return wrapper

@login_required

def akses_fitur_premium(user):

print(f"Selamat datang {[Link]} di fitur premium")

```

---

### **Dekorator dengan Argumen**

```python

def repeat(n):

def decorator(func):

def wrapper(*args, **kwargs):

for _ in range(n):

result = func(*args, **kwargs)

return result

return wrapper

return decorator

@repeat(3)

def hello():

print("Halo!")

hello()

```

**Output:**

```

Halo!
Halo!

Halo!

```

---

### **Dekorator untuk Kelas**

```python

def tambah_method(func):

def wrapper(self):

print("Method baru ditambahkan!")

return func(self)

return wrapper

class Contoh:

@tambah_method

def existing_method(self):

print("Method asli")

obj = Contoh()

obj.existing_method()

```

---

### **Dekorator Bawaan Python**

1. `@staticmethod`: Method statis (tidak butuh akses ke instance/kelas)

2. `@classmethod`: Method kelas (menerima kelas sebagai argumen


pertama)
3. `@property`: Mengubah method menjadi atribut

```python

class Circle:

def __init__(self, radius):

self._radius = radius

@property

def radius(self):

return self._radius

@[Link]

def radius(self, value):

if value > 0:

self._radius = value

```

---

### **Fakta Penting tentang Dekorator**

1. **Berantai Dekorator**:

```python

@decorator1

@decorator2

def my_func():

...

# Ekivalen dengan: my_func = decorator1(decorator2(my_func))

```

2. **Mengatasi Masalah Metadata**:


Gunakan `[Link]` untuk mempertahankan nama dan docstring
fungsi asli:

```python

from functools import wraps

def decorator(func):

@wraps(func)

def wrapper(*args, **kwargs):

...

return wrapper

```

3. **Dekorator sebagai Kelas**:

```python

class DecoratorAsClass:

def __init__(self, func):

[Link] = func

def __call__(self, *args, **kwargs):

print("Sebelum eksekusi")

return [Link](*args, **kwargs)

```

---

### **Kapan Menggunakan Dekorator?**

1. Logging dan monitoring

2. Autentikasi dan otorisasi

3. Caching/memoization
4. Validasi input

5. Pengendalian akses

6. Pengukuran kinerja

7. Error handling

Dekorator adalah salah satu fitur Python yang membuat kode menjadi
**lebih elegan, modular, dan mudah dipelihara**. Dengan penggunaannya
yang tepat, Anda bisa menciptakan kode yang bersih dan profesional! 🐍✨

-----------------------------------------------------------------------

#### **8. Manajemen Berkas**

- **Buka Berkas (Open)**

### **Membuka Berkas (File) dalam Python**

Membuka berkas (file) di Python adalah proses **mengakses dan


menghubungkan** program Python dengan sebuah file di sistem
penyimpanan untuk melakukan operasi seperti membaca, menulis, atau
menambahkan data.

Operasi ini menggunakan fungsi bawaan `open()` dan merupakan langkah


pertama sebelum melakukan manipulasi file.

---

#### **Sintaks Dasar Membuka File**

```python

file_object = open(file_path, mode)

```

- **`file_path`**: Jalur ke file (misal: `"[Link]"` atau `"folder/[Link]"`)


- **`mode`**: Mode operasi (baca, tulis, tambah, dll)

- **`file_object`**: Objek file yang digunakan untuk berinteraksi dengan


berkas

---

### **Mode Operasi File**

Mode menentukan bagaimana file akan ditangani:

| Mode | Keterangan | Contoh


Penggunaan |

|------|----------------------------------------------------------------------------|-------------------
-------------|

| `'r'` | **Read** (baca saja) - Mode default |


Membaca file teks |

| `'w'` | **Write** (tulis) - Membuat file baru atau menimpa file yang sudah
ada | Menyimpan output program |

| `'a'` | **Append** (tambahkan) - Menambahkan data di akhir file tanpa


menghapus | Logging data |

| `'x'` | **Create** (buat) - Membuat file baru, gagal jika file sudah ada
| Membuat file konfigurasi baru |

| `'b'` | **Binary** (biner) - Mode biner (digabung dengan mode lain)


| File gambar/executable |

| `'t'` | **Text** (teks) - Mode teks (default) | File


teks biasa |

| `'+'` | **Update** (baca+tulis) - Membuka untuk update (baca dan tulis)


| File database sederhana |

Contoh kombinasi mode:

- `'rb'`: Baca file biner

- `'w+'`: Tulis dan baca (timpa file)

- `'a+'`: Tambah dan baca


---

### **Cara Aman Membuka File (Menggunakan `with`)**

Direkomendasikan menggunakan pernyataan `with` karena **secara


otomatis menutup file** setelah blok selesai, bahkan jika terjadi error.

```python

with open('[Link]', 'r') as file:

data = [Link]()

print(data)

# File otomatis ditutup di sini

```

---

### **Operasi Dasar pada File Terbuka**

1. **Membaca File**

```python

# Baca seluruh konten

with open('[Link]', 'r') as f:

content = [Link]()

# Baca per baris (list)

with open('[Link]', 'r') as f:

lines = [Link]()

# Baca baris per baris (efisien memori)

with open('[Link]', 'r') as f:


for line in f:

print([Link]())

```

2. **Menulis ke File**

```python

# Menulis string (menimpa file jika sudah ada)

with open('[Link]', 'w') as f:

[Link]("Baris pertama\n")

[Link]("Baris kedua\n")

# Menulis list string

lines = ["Line 1\n", "Line 2\n"]

with open('[Link]', 'w') as f:

[Link](lines)

```

3. **Menambahkan ke File**

```python

with open('[Link]', 'a') as f:

[Link](f"{[Link]()}: Event terjadi\n")

```

---

### **Pentingnya Menutup File**

File yang terbuka **harus ditutup** setelah selesai digunakan untuk:

1. Membebaskan sumber daya sistem

2. Memastikan semua data benar-benar ditulis


3. Mencegah korupsi data

4. Menghindari error "too many open files"

**Cara manual (tidak direkomendasikan):**

```python

file = open('[Link]', 'r')

try:

data = [Link]()

finally:

[Link]() # Selalu ditutup meski error

```

---

### **Pemrosesan File Binary**

```python

# Salin file gambar

with open('[Link]', 'rb') as src:

with open('[Link]', 'wb') as dst:

[Link]([Link]())

```

---

### **Pengecualian (Exceptions) Umum**

- `FileNotFoundError`: File tidak ditemukan (mode `'r'`)

- `PermissionError`: Izin akses ditolak

- `IsADirectoryError`: Mencoba membuka direktori

- `UnicodeDecodeError`: Kesalahan decoding teks


**Contoh penanganan error:**

```python

try:

with open('file_tidak_ada.txt', 'r') as f:

print([Link]())

except FileNotFoundError:

print("File tidak ditemukan!")

except Exception as e:

print(f"Error tak terduga: {e}")

```

---

### **Best Practices**

1. Selalu gunakan `with` statement

2. Tentukan encoding teks secara eksplisit (misal: `encoding='utf-8'`)

3. Gunakan path relatif/absolut dengan benar

4. Handle kemungkinan exception

5. Untuk file besar, gunakan iterasi per baris/chunk

**Contoh dengan encoding:**

```python

with open('[Link]', 'r', encoding='utf-8') as f:

content = [Link]()

```

---
### **Contoh Praktis Lengkap**

```python

# Salin isi file dengan progress bar

def copy_file(src, dst, buffer_size=1024):

import os

total_size = [Link](src)

copied = 0

with open(src, 'rb') as source:

with open(dst, 'wb') as target:

while True:

buffer = [Link](buffer_size)

if not buffer:

break

[Link](buffer)

copied += len(buffer)

print(f"Progress: {copied/total_size:.2%}", end='\r')

print("\nSelesai!")

copy_file('video.mp4', 'backup.mp4')

```

Dengan memahami cara membuka dan mengelola file di Python, Anda


dapat membuat program yang berinteraksi dengan sistem penyimpanan
data secara efektif dan aman! 🐍💾

- **Tutup Berkas (Close)**

### **Menutup Berkas (File) dalam Python**


Menutup berkas adalah proses **melepaskan sumber daya sistem** yang
digunakan oleh file yang telah dibuka dan **memastikan semua operasi
tulis diselesaikan** dengan benar. Ini adalah langkah kritis dalam
manajemen file untuk mencegah kebocoran sumber daya dan
memastikan integritas data.

---

#### **Mengapa Menutup File Penting?**

1. **Membebaskan Deskriptor File**:

- Sistem operasi membatasi jumlah file yang bisa terbuka sekaligus

- File yang tidak ditutup akan memakai slot berharga ini

2. **Memastikan Flushing Data**:

- Data yang ditulis mungkin masih dalam buffer memori

- Penutupan file memaksa penulisan akhir ke penyimpanan fisik

3. **Mencegah Korupsi Data**:

- Memastikan semua operasi tulis selesai sebelum program berakhir

4. **Membuka Kunci File**:

- File yang terbuka mungkin dikunci oleh sistem operasi

- Penutupan melepas kunci sehingga aplikasi lain bisa mengakses

---

### **Cara Menutup File**

#### 1. Metode Manual (dengan `close()`)

```python

file = open('[Link]', 'r')

try:

data = [Link]()
# Proses data

finally:

[Link]() # Selalu ditutup meskipun terjadi error

```

#### 2. Cara Otomatis (dengan `with` statement -


**Direkomendasikan**)

```python

with open('[Link]', 'r') as file:

data = [Link]()

# Proses data

# File otomatis ditutup di sini, bahkan jika terjadi exception

```

---

### **Konsekuensi Jika Tidak Menutup File**

#### Contoh Kasus Berbahaya:

```python

files = []

for i in range(10000):

[Link](open(f'temp_{i}.txt', 'w')) # Membuka ribuan file tanpa


ditutup

# Akan menyebabkan:

# OSError: [Errno 24] Too many open files

```

#### Dampak:
1. **Kebocoran Memori**: Sumber daya sistem tidak dilepaskan

2. **Data Hilang**: Konten buffer tidak ditulis ke disk

3. **Error Sistem**: Program crash karena kehabisan deskriptor file

4. **File Terkunci**: File tidak bisa diakses aplikasi lain

---

### **Praktik Terbaik Penutupan File**

1. **Selalu gunakan `with` statement**:

```python

with open('[Link]', 'r') as f1, open('[Link]', 'w') as f2:

data = [Link]()

[Link]([Link]())

```

2. **Pastikan penutupan di blok `finally`** jika tidak bisa pakai `with`:

```python

file = None

try:

file = open('[Link]', 'rb')

# Operasi file

except IOError as e:

print(f"Error: {e}")

finally:

if file is not None:

[Link]() # Penutupan jaminan

```

3. **Verifikasi penutupan**:
```python

file = open('[Link]', 'w')

[Link]("Hello")

[Link]()

print([Link]) # True jika berhasil ditutup

```

---

### **Kasus Khusus Penutupan File**

#### 1. File dalam Loop

```python

for filename in ['[Link]', '[Link]', '[Link]']:

with open(filename, 'r') as f: # Ditutup otomatis tiap iterasi

print([Link]())

```

#### 2. File dengan Write-Back

```python

with open('[Link]', 'r+') as file:

lines = [Link]()

[Link](0) # Kembali ke awal file

[Link]([[Link]() for l in lines])

[Link]() # Potong sisa konten lama

# Perubahan disimpan dan file ditutup

```
---

### **Tanda bahwa File Telah Tertutup**

Setelah file ditutup:

1. Semua operasi baca/tulis akan gagal

2. Objek file memiliki atribut `closed` = `True`

3. Metode `close()` bisa dipanggil berulang tanpa error

```python

f = open('[Link]', 'w')

[Link]()

print([Link]) # True

[Link]("Coba") # ValueError: I/O operation on closed file

```

---

### **Hubungan dengan Garbage Collector**

- Python secara otomatis akan menutup file ketika objek file di-**garbage
collected**

- **Tapi jangan bergantung pada ini!**:

- Waktu garbage collection tidak pasti

- Dalam implementasi CPython, reference counting bisa menutup file


segera

- Tapi di implementasi lain (PyPy, Jython) bisa tertunda

- **Explicit is better than implicit**

---
### **Kesimpulan**

Menutup file adalah:

1. **Kewajiban** untuk manajemen sumber daya yang baik

2. **Jaminan integritas data** untuk operasi tulis

3. **Praktik wajib** dalam pemrograman Python profesional

Dengan selalu menggunakan `with` statement, Anda memastikan:

- File ditutup otomatis

- Kode lebih bersih dan aman

- Tidak ada kebocoran sumber daya

Pola ini berlaku untuk semua tipe file: teks, biner, socket, koneksi
database, dan sumber daya lain yang perlu dibersihkan! 🔒🐍

- **Baca Berkas (Read)**

### **Membaca Berkas (File) dalam Python**

Membaca berkas adalah proses **mengakses dan mengambil konten**


dari sebuah file yang tersimpan di sistem penyimpanan ke dalam program
Python. Operasi ini dilakukan setelah file berhasil dibuka dan sebelum
ditutup.

---

#### **Alur Dasar Membaca File**

1. Buka file dengan mode baca (`'r'` atau `'rb'`)

2. Lakukan operasi baca menggunakan metode yang sesuai

3. Tutup file (otomatis dengan `with` statement)

```python
with open('[Link]', 'r') as file:

content = [Link]() # Proses membaca

```

---

### **Metode-Metode Penting untuk Membaca**

#### 1. `read([size])`

- Membaca seluruh konten atau sejumlah karakter/byte tertentu

- Mengembalikan string (mode teks) atau bytes object (mode biner)

```python

# Baca seluruh file

with open('[Link]', 'r') as f:

seluruh_konten = [Link]()

# Baca 100 karakter pertama

with open('[Link]', 'r') as f:

potongan = [Link](100)

```

#### 2. `readline([size])`

- Membaca satu baris sekaligus

- Opsional: batas jumlah karakter/byte per baris

```python

with open('[Link]', 'r') as f:

baris1 = [Link]() # Baris pertama


baris2 = [Link]() # Baris kedua

```

#### 3. `readlines()`

- Membaca semua baris dan mengembalikan list of strings

- Setiap elemen list adalah satu baris

```python

with open('[Link]', 'r') as f:

semua_baris = [Link]()

# Contoh: ['Nama,Usia\n', 'Budi,18\n', 'Ani,17\n']

```

---

### **Teknik Membaca File Efisien**

#### 1. Iterasi Langsung per Baris (Rekomendasi)

- Paling efisien untuk file besar

- Hanya menyimpan satu baris di memori setiap saat

```python

with open('data_large.txt', 'r') as file:

for baris in file:

print([Link]()) # Proses per baris

```

#### 2. Membaca dalam Chunk (Potongan)

- Berguna untuk file sangat besar atau biner


- Kontrol penuh atas ukuran buffer

```python

CHUNK_SIZE = 4096 # 4KB per potongan

with open('video.mp4', 'rb') as file:

while True:

chunk = [Link](CHUNK_SIZE)

if not chunk: # Akhir file

break

process_chunk(chunk)

```

---

### **Parameter Penting saat Membaca**

#### 1. Encoding (Untuk File Teks)

- Tentukan encoding karakter secara eksplisit

- Hindari kesalahan decoding tak terduga

```python

with open('data_unicode.txt', 'r', encoding='utf-8') as f:

content = [Link]()

```

#### 2. Penanganan Karakter Baru

- Python otomatis mengonversi `\n`, `\r\n` ke `\n`

- Nonaktifkan dengan `newline=''`:


```python

with open('file_windows.txt', 'r', newline='') as f:

content = [Link]() # Pertahankan \r\n asli

```

---

### **Kesalahan Umum saat Membaca**

#### 1. FileNotFoundError

```python

try:

with open('tidak_ada.txt', 'r') as f:

print([Link]())

except FileNotFoundError:

print("File tidak ditemukan!")

```

#### 2. UnicodeDecodeError

```python

try:

with open('[Link]', 'r') as f: # Salah mode!

print([Link]())

except UnicodeDecodeError:

print("Gunakan mode 'rb' untuk file biner!")

```

#### 3. Kesalahan Lokasi Pointer


```python

with open('[Link]', 'r+') as f:

print([Link]()) # Baca sampai akhir

[Link]("Data baru") # Pointer ada di akhir file

[Link](0) # Kembali ke awal untuk baca ulang

print([Link]())

```

---

### **Best Practices Membaca File**

1. **Gunakan `with` statement**:

- Jaminan file ditutup otomatis

- Lebih bersih dan aman

2. **Pilih metode yang sesuai**:

- File kecil → `read()`

- File besar → iterasi per baris

- Format terstruktur → baca per baris + parsing

3. **Selalu tentukan encoding**:

```python

open('[Link]', 'r', encoding='utf-8')

```

4. **Tangani kemungkinan error**:

```python

try:
# Operasi baca

except (FileNotFoundError, PermissionError) as e:

# Penanganan khusus

except Exception as e:

# Penanganan umum

```

---

### **Contoh Praktis: Membaca File CSV**

```python

import csv

with open('[Link]', 'r', encoding='utf-8') as f:

reader = [Link](f)

for row in reader:

print(f"{row['Nama']}: {row['Email']}")

```

### **Membaca File JSON**

```python

import json

with open('[Link]', 'r') as f:

config = [Link](f)

print(config['api_key'])

```

### **Membaca File Binary (Gambar)**


```python

with open('[Link]', 'rb') as f:

header = [Link](4) # 4 byte pertama

if header == b'\xff\xd8\xff\xe0':

print("File JPEG valid")

```

---

### **Poin Kunci Membaca File**

- Operasi baca **tidak mengubah** file asli

- Pointer baca bergerak otomatis setelah operasi

- Gunakan `seek(0)` untuk kembali ke awal file

- Mode baca (`'r'`/`'rb'`) mewajibkan file sudah ada

- Untuk operasi kompleks, gunakan modul khusus (`csv`, `json`, `pickle`,


dll.)

Dengan menguasai teknik membaca file, Anda bisa memproses segala


jenis data eksternal mulai dari teks sederhana hingga dataset besar dan
file biner kompleks! 📖🐍

- **Tulis Berkas (Write)**

### **Menulis Berkas (File) dalam Python**

Menulis berkas adalah proses **menyimpan data dari program Python**


ke dalam file di sistem penyimpanan. Operasi ini memungkinkan Anda
membuat file baru, mengubah konten file yang ada, atau menambahkan
data ke file yang sudah ada.

---
#### **Alur Dasar Menulis File**

1. Buka file dengan mode tulis (`'w'`), tambah (`'a'`), atau baca-tulis
(`'r+'`/`'w+'`)

2. Lakukan operasi tulis menggunakan metode yang sesuai

3. Tutup file untuk memastikan data tersimpan sempurna

```python

with open('[Link]', 'w') as file:

[Link]("Data yang akan disimpan") # Proses menulis

```

---

### **Mode Menulis Penting**

| Mode | Keterangan | Perilaku Jika


File Sudah Ada |

|------|----------------------------------------------------------------------------|-------------------
------------------|

| `'w'` | **Write** (Tulis) | Menimpa


seluruh konten file |

| `'a'` | **Append** (Tambahkan) |


Menambahkan di akhir file |

| `'x'` | **Exclusive Creation** (Buat baru) |


Gagal jika file sudah ada |

| `'w+'`| **Write + Read** (Tulis dan Baca) |


Menimpa file, lalu bisa dibaca |

| `'a+'`| **Append + Read** (Tambahkan dan Baca)


| Menambahkan, lalu bisa dibaca |

---
### **Metode-Metode Penting untuk Menulis**

#### 1. `write(string)`

- Menulis string ke file

- Untuk file teks: mengembalikan jumlah karakter yang ditulis

- Untuk file biner: menulis byte

```python

with open('[Link]', 'w') as f:

[Link]("Baris pertama\n")

[Link]("Baris kedua\n")

chars_written = [Link]("Baris ketiga") # Mengembalikan jumlah


karakter

```

#### 2. `writelines(sequence)`

- Menulis list string ke file

- Tidak otomatis menambahkan newline

```python

lines = ["Nama: Budi\n", "Umur: 25\n", "Kota: Jakarta\n"]

with open('[Link]', 'w') as f:

[Link](lines)

```

---

### **Teknik Menulis Efektif**


#### 1. Menulis dengan Formatting

```python

name = "Ani"

age = 22

with open('[Link]', 'w') as f:

[Link](f"Nama: {name}\nUmur: {age}\n") # f-string

[Link]("Alamat: {}\n".format("Bandung")) # format()

```

#### 2. Menulis Data Terstruktur (CSV)

```python

import csv

data = [

['Nama', 'Email'],

['Budi', 'budi@[Link]'],

['Ani', 'ani@[Link]']

with open('[Link]', 'w', newline='') as f:

writer = [Link](f)

[Link](data)

```

#### 3. Menulis JSON

```python

import json

user = {
"id": 123,

"name": "Diana",

"roles": ["admin", "editor"]

with open('[Link]', 'w') as f:

[Link](user, f, indent=4) # indent untuk format rapi

```

---

### **Best Practices Menulis File**

1. **Gunakan `with` statement**:

```python

with open('[Link]', 'w') as f:

[Link]("Data aman")

```

2. **Tentukan encoding teks**:

```python

with open('[Link]', 'w', encoding='utf-8') as f:

[Link]("日本語も OK")

```

3. **Handle error penulisan**:

```python

try:

with open('[Link]', 'a') as f:


[Link]("Log entry\n")

except IOError as e:

print(f"Gagal menulis: {e}")

```

4. **Flush data secara manual** jika perlu:

```python

with open('[Link]', 'w') as f:

[Link]("Data awal")

[Link]() # Paksa tulis ke disk sekarang

# Proses panjang...

[Link]("Data akhir")

```

---

### **Perilaku Khusus Mode Tulis**

#### 1. Mode `'w'` (Write)

- **Membuat file baru** jika belum ada

- **Mengosongkan file** jika sudah ada

- **Pointer di awal file**

```python

# File akan berisi: "Konten baru"

with open('[Link]', 'w') as f:

[Link]("Konten baru")

```
#### 2. Mode `'a'` (Append)

- **Membuat file baru** jika belum ada

- **Pointer di akhir file** jika sudah ada

- **Tidak mengubah konten** yang sudah ada

```python

# File sebelum: "Hello"

# File setelah: "Hello World!"

with open('[Link]', 'a') as f:

[Link](" World!")

```

---

### **Menulis File Binary**

```python

# Salin file gambar

with open('[Link]', 'rb') as src:

with open('[Link]', 'wb') as dst:

[Link]([Link]())

# Membuat file biner custom

data_bytes = bytes([0x48, 0x65, 0x6C, 0x6C, 0x6F]) # "Hello"

with open('[Link]', 'wb') as f:

[Link](data_bytes)

```

---
### **Kesalahan Umum saat Menulis**

1. **Tidak menutup file**:

- Data mungkin masih di buffer dan belum tersimpan

```python

f = open('[Link]', 'w')

[Link]("Penting!")

# Jika program crash di sini, data mungkin hilang

[Link]() # Selalu panggil close()

```

2. **Mode salah**:

```python

with open('[Link]', 'x') as f: # Mode exclusive

[Link]("Data") # FileExistsError jika file sudah ada

```

3. **Permission denied**:

```python

try:

with open('C:/system/[Link]', 'w') as f:

[Link]("Test")

except PermissionError:

print("Tidak punya izin menulis")

```

---

### **Contoh Praktis Lengkap**


#### Logging System dengan Rotasi File

```python

import datetime

import os

def write_log(message):

filename = f"log_{[Link]()}.txt"

with open(filename, 'a') as f:

timestamp = [Link]().strftime("%Y-%m-%d %H:%M:


%S")

[Link](f"[{timestamp}] {message}\n")

# Rotasi: hapus log > 7 hari

for file in [Link]():

if [Link]("log_") and [Link](".txt"):

file_date = file[4:-4]

if ([Link]() -
[Link](file_date)).days > 7:

[Link](file)

write_log("Aplikasi dimulai")

write_log("Proses data selesai")

```

---

### **Poin Kunci Menulis File**

- Operasi menulis **dapat mengubah/membuat** file


- Data tidak langsung ke disk sampai buffer penuh/file ditutup

- Gunakan `flush()` untuk paksa tulis segera

- Mode `'w'` berbahaya karena menimpa data tanpa peringatan

- Untuk file penting, gunakan pendekatan write-temporary-rename:

```python

import os

with open('[Link]', 'w') as tmp:

[Link]("Konten baru")

[Link]('[Link]', '[Link]') # Operasi atomik

```

Dengan menguasai teknik menulis file, Anda dapat menyimpan output


program, membuat laporan, menyimpan konfigurasi, dan membangun
sistem persistensi data yang andal! 💾🐍

- **Hapus Berkas (Delete)**

Dalam Python, **menghapus berkas (file)** berarti menghapus file secara


permanen dari sistem penyimpanan. Operasi ini dilakukan menggunakan
modul bawaan Python seperti `os` atau `pathlib`. Berikut penjelasan
lengkapnya:

---

### **1. Menggunakan Modul `os`**

Modul `os` menyediakan fungsi `[Link]()` untuk menghapus file.

#### Contoh Dasar:

```python

import os
# Menghapus file bernama "[Link]"

[Link]("[Link]")

```

#### Penanganan Error:

Saat file tidak ditemukan, Python akan melemparkan `FileNotFoundError`.


Gunakan blok `try-except` untuk menanganinya:

```python

import os

try:

[Link]("[Link]")

print("Berkas berhasil dihapus!")

except FileNotFoundError:

print("Berkas tidak ditemukan!")

except PermissionError:

print("Tidak memiliki izin untuk menghapus!")

except Exception as e:

print(f"Terjadi error: {e}")

```

---

### **2. Menggunakan `pathlib` (Python 3.4+)**

`pathlib` adalah alternatif modern yang lebih intuitif. Gunakan metode


`.unlink()`.

#### Contoh:

```python

from pathlib import Path


file_path = Path("[Link]")

# Hapus file jika ada

if file_path.exists():

file_path.unlink()

print("Berkas dihapus!")

else:

print("Berkas tidak ada.")

```

---

### **Perhatian Penting:**

1. **Penghapusan Permanen**:

File yang dihapus **tidak bisa dipulihkan** dari Recycle Bin/Trash.

2. **Izin File**:

Pastikan program memiliki izin untuk menghapus file.

3. **Cek Keberadaan File**:

Gunakan `[Link]()` atau `[Link]()` untuk memeriksa


apakah file ada sebelum dihapus.

---

### **Hapus Direktori (Folder)**

- **Hapus direktori kosong**:

```python
[Link]("nama_folder") # Hanya bekerja jika folder kosong

```

- **Hapus direktori beserta isinya**:

```python

import shutil

[Link]("nama_folder") # Hapus folder + semua kontennya

```

---

### **Best Practices:**

- Selalu gunakan penanganan error (`try-except`).

- Verifikasi path file sebelum menghapus.

- Gunakan path absolut untuk menghindari kesalahan lokasi.

Dengan memahami metode di atas, Anda bisa mengelola penghapusan


berkas dalam Python secara aman dan efektif.

-----------------------------------------------------------------------

#### **9. Penanganan Kesalahan**

- **Error & Exception Handling**

### **Error dan Exception Handling dalam Python**

#### **1. Error (Kesalahan)**

Dalam Python, **error** adalah masalah yang menghentikan eksekusi


program. Terdapat dua jenis utama:

- **Syntax Error**:

Kesalahan penulisan kode (misalnya: lupa titik dua, salah eja keyword).

Contoh:
```python

print("Hello" # Error: Kurang tanda kurung tutup

```

- **Runtime Error (Exception)**:

Kesalahan yang terjadi saat program berjalan (misalnya: pembagian


dengan nol, file tidak ditemukan).

Contoh:

```python

print(10 / 0) # ZeroDivisionError

```

---

#### **2. Exception (Pengecualian)**

**Exception** adalah jenis runtime error yang bisa "ditangkap" dan


ditangani agar program tidak berhenti tiba-tiba. Python memiliki banyak
built-in exception seperti:

- `ZeroDivisionError`: Pembagian dengan nol

- `FileNotFoundError`: File tidak ditemukan

- `IndexError`: Indeks di luar jangkauan list

- `KeyError`: Key tidak ada dalam dictionary

- `TypeError`: Operasi dengan tipe data tidak sesuai

---

#### **3. Exception Handling (Penanganan Pengecualian)**

Mekanisme untuk menangkap dan menangani exception sehingga


program bisa melanjutkan atau memberi pesan error yang jelas.
Menggunakan blok:
- **`try`**: Menjalankan kode yang berpotensi error

- **`except`**: Menangkap dan menangani exception

- **`else`**: Dijalankan jika tidak ada exception

- **`finally`**: Selalu dijalankan (cocok untuk cleanup)

---

### **Contoh Implementasi**

#### Contoh 1: Menangkap Exception Spesifik

```python

try:

file = open("[Link]", "r")

print([Link]())

except FileNotFoundError:

print("Error: File tidak ditemukan!")

except PermissionError:

print("Error: Tidak ada izin akses!")

```

#### Contoh 2: Menangkap Semua Exception

```python

try:

angka = int(input("Masukkan angka: "))

hasil = 10 / angka

except Exception as e: # Menangkap semua error

print(f"Terjadi error: {type(e).__name__} - {e}")

else:

print(f"Hasil: {hasil}")

finally:
print("Proses selesai.")

```

#### Contoh 3: Menggunakan `else` dan `finally`

```python

try:

print("Mencoba koneksi database...")

# Simulasi kode berisiko

except ConnectionError:

print("Koneksi gagal!")

else:

print("Data berhasil diambil!") # Dijalankan jika tidak ada error

finally:

print("Tutup koneksi...") # Selalu dijalankan

```

---

### **Best Practices**

1. **Tangkap exception spesifik** ketimbang menggunakan `except`


umum.

❌ Buruk: `except:`

✅ Baik: `except FileNotFoundError:`

2. **Gunakan pesan error informatif**:

```python

except ValueError as e:

print(f"Input invalid: {e}")

```
3. **Manfaatkan `finally` untuk cleanup**:

```python

try:

file = open("[Link]")

finally:

[Link]() # Selama tutup file meskipun error

```

4. **Lempar ulang exception** dengan `raise` jika perlu:

```python

except ValueError:

print("Log error...")

raise # Lempar exception ke level atas

```

---

### **Membuat Custom Exception**

Anda bisa membuat exception khusus dengan mewarisi kelas `Exception`:

```python

class SaldoTidakCukupError(Exception):

pass

def tarik_uang(saldo):

if saldo < 1000:

raise SaldoTidakCukupError("Saldo minimal harus 1000")

try:
tarik_uang(500)

except SaldoTidakCukupError as e:

print(f"Error: {e}")

```

---

### **Kesimpulan**

- **Error** menghentikan program, **exception** adalah subset error


yang bisa ditangani.

- **Exception handling** memungkinkan program merespons error secara


elegan.

- Gunakan kombinasi `try`/`except`/`else`/`finally` untuk kontrol


maksimal.

- Selalu tangani exception dengan spesifik dan informatif!

-----------------------------------------------------------------------

#### **10. Event Handling**

Event handling terutama masuk ke dalam:

1. **Pemrograman Berorientasi Objek (OOP)** - sebagai method dalam


class

2. **Fungsi** - sebagai callback/handler

3. **Konsep Lanjutan** - implementasi pola desain

### Macam-Macam Metode Event Handling di Python (GUI Framework)

#### **1. Mouse/Touch Events**

- **`on_press` / `on_touch_down`**

- **Penjelasan**: Dipicu saat jari/mouse *baru menyentuh* widget


- **Waktu Penggunaan**:

- Feedback visual instan (animasi tekan)

- Aksi yang harus cepat (misal: tombol tembak di game)

- **`on_release` / `on_touch_up`**

- **Penjelasan**: Dipicu saat jari/mouse *dilepaskan* dari widget

- **Waktu Penggunaan**:

- Konfirmasi aksi utama (submit form, pilih menu)

- Operasi kritis yang perlu konfirmasi (hapus data)

- **`on_touch_move`**

- **Penjelasan**: Dipicu saat jari/mouse *bergerak* selama menyentuh

- **Waktu Penggunaan**:

- Drag-and-drop elements

- Drawing canvas

- Slider interaction

#### **2. Keyboard Events**

- **`on_key_down`**

- **Penjelasan**: Dipicu saat tombol keyboard *ditekan*

- **Waktu Penggunaan**:

- Realtime input (game controls)

- Shortcut dengan kombinasi tombol (Ctrl+S)

- **`on_key_up`**

- **Penjelasan**: Dipicu saat tombol keyboard *dilepas*

- **Waktu Penggunaan**:

- Finalisasi input teks

- Aksi setelah tombol dihold (zoom in/out)


#### **3. Focus Events**

- **`on_focus`**

- **Penjelasan**: Dipicu saat widget *menerima fokus input*

- **Waktu Penggunaan**:

- Auto-select text di TextInput

- Tampilkan virtual keyboard di mobile

- **`on_blur`**

- **Penjelasan**: Dipicu saat widget *kehilangan fokus*

- **Waktu Penggunaan**:

- Validasi form input

- Auto-save data

#### **4. Component-Specific Events**

- **`on_text` (TextInput)**

- **Penjelasan**: Dipicu saat *teks berubah*

- **Waktu Penggunaan**:

- Live search filter

- Character counter

- **`on_value` (Slider/Checkbox)**

- **Penjelasan**: Dipicu saat *nilai berubah*

- **Waktu Penggunaan**:

- Real-time settings adjustment

- Dynamic UI updates

- **`on_active` (Tabs/Accordion)**

- **Penjelasan**: Dipicu saat *tab/panel diaktifkan*


- **Waktu Penggunaan**:

- Lazy loading konten

- Context switching

#### **5. Lifecycle Events**

- **`on_pre_enter` (Screen)**

- **Penjelasan**: Dipicu *sebelum* screen ditampilkan

- **Waktu Penggunaan**:

- Persiapan data awal

- Permission checks

- **`on_enter` (Screen)**

- **Penjelasan**: Dipicu saat screen *aktif*

- **Waktu Penggunaan**:

- Animasi transisi

- Auto-refresh data

- **`on_leave` (Screen)**

- **Penjelasan**: Dipicu saat screen *tidak aktif*

- **Waktu Penggunaan**:

- Pause background processes

- Save temporary state

#### **6. Gesture Events (Mobile Specific)**

- **`on_long_press`**

- **Penjelasan**: Dipicu saat *tap-and-hold* (biasanya >500ms)

- **Waktu Penggunaan**:

- Context menus

- Object selection
- **`on_double_tap`**

- **Penjelasan**: Dipicu saat *dua kali tap cepat*

- **Waktu Penggunaan**:

- Zoom to fit

- Like/favorite actions

#### **7. Custom Events**

```python

# Contoh pembuatan custom event di Kivy

class DownloadCompleteEvent(Event):

pass

# Memicu event

def on_download_finished(self):

[Link]('on_download_complete')

# Mendaftar handler

[Link](on_download_complete=self.update_ui)

```

### Best Practices Penggunaan Event

1. **Hindari Blocking Operations di Handler**

```python

# Buruk

def on_press(self):

[Link](5) # Freeze UI!

# Baik
def on_release(self):

[Link](target=self.heavy_operation).start()

```

2. **Gunakan Event Delegation untuk Kompleks**

```python

# Parent menangani event untuk banyak child

grid = GridLayout()

[Link](on_touch_down=self.handle_grid_touch)

```

3. **Unbind untuk Cegah Memory Leak**

```python

def cleanup(self):

[Link](on_press=[Link])

```

4. **Prioritaskan UX Flow**

```mermaid

graph TD

A[User Action] --> B{Type}

B -->|Instant Feedback| C[on_press]

B -->|Final Action| D[on_release]

B -->|Data Entry| E[on_text]

```

### Framework-Specific Notes

- **Kivy/KivyMD**: `on_touch_down`, `on_touch_up`, `on_text`

- **Tkinter**: `<Button-1>`, `<KeyPress>`, `<FocusIn>`


- **PyQt**: `mousePressEvent()`, `keyReleaseEvent()`

- **Django Channels**: `[Link]` (untuk WebSockets)

Pemilihan event yang tepat meningkatkan:

- **Responsivitas** (respon <100ms)

- **Konsumsi Resource** (hindari over-handling)

- **User Experience** (alur interaksi natural)

- **Maintainability** (pemisahan concern)

______________

### Perbedaan `bind` dan `unbind` dalam Event Handling

#### **`bind()`**

- **Apa itu**: Metode untuk menghubungkan event dengan handler


function

- **Kegunaan**: Mendaftarkan fungsi yang akan dipanggil saat event


terjadi

- **Mekanisme**: Membuat hubungan antara event dan callback

- **Contoh**:

```python

[Link](on_press=self.handle_press) # Hubungkan event press ke


handler

```

#### **`unbind()`**

- **Apa itu**: Metode untuk melepaskan hubungan event-handler

- **Kegunaan**: Mencabut pendaftaran handler dari event

- **Mekanisme**: Memutus hubungan antara event dan callback

- **Contoh**:
```python

[Link](on_press=self.handle_press) # Lepaskan handler dari


event

```

---

### Perbedaan Utama

| Karakteristik | `bind()` | `unbind()` |

|---------------------|-----------------------------------|-----------------------------------|

| **Tujuan** | Membuat koneksi event-handler | Memutus koneksi


event-handler |

| **Efek** | Handler aktif saat event terjadi | Handler berhenti


merespons event |

| **Penggunaan Khas** | Saat inisialisasi komponen | Saat


cleanup/dinamis ubah behavior|

| **Risiko** | Memory leak jika tidak di-unbind | UI tidak responsif


jika di-unbind salah |

---

### Analogi Sederhana

- **`bind()`** → Berlangganan newsletter (dapat email saat ada update)

- **`unbind()`** → Berhenti berlangganan (tidak dapat email lagi)

---

### Kapan Menggunakan?

**Gunakan `bind()` saat**:

1. Inisialisasi komponen UI

2. Butuh respons terhadap interaksi pengguna


3. Dinamis menambah handler baru

**Gunakan `unbind()` saat**:

1. Komponen dihancurkan

2. Handler tidak diperlukan lagi

3. Mengganti handler dinamis

4. Mencegah memory leak

---

### Contoh Praktis

```python

class LoginScreen(MDScreen):

def __init__(self, **kwargs):

super().__init__(**kwargs)

self.submit_btn.bind(on_release=self.handle_login) # BIND saat init

def handle_login(self, instance):

print("Login attempted")

def cleanup(self):

self.submit_btn.unbind(on_release=self.handle_login) # UNBIND saat


tidak perlu

```

---

### Bahaya Tidak Melakukan Unbind

```mermaid
graph LR

A[Bind Handler] --> B[Event Terjadi]

B --> C[Handler Dipanggil]

C --> D[Objek Masih Tereferensi?]

D -->|Ya| E[Memory Leak]

D -->|Tidak| F[OK]

```

**Efek**:

- Memory usage meningkat

- Aksi ganda saat event terjadi

- Perilaku tidak terduga

---

### Best Practices

1. **Pattern Matching**:

```python

# Bind

[Link](on_press=lambda x: [Link](x))

# Unbind

for callback in [Link].get_property('on_press'):

if "action" in str(callback):

[Link](on_press=callback)

```

2. **Weak Reference** (PyQt/PySide):

```python
[Link]([Link], [Link])

```

3. **Automatic Cleanup**:

```python

def on_leave(self):

self.unbind_handlers() # Otomatis unbind saat tinggalkan screen

```

4. **One-time Bind**:

```python

def temp_handler(instance):

print("One-time action")

[Link](on_press=temp_handler) # Auto-unbind setelah


eksekusi

[Link](on_press=temp_handler)

```

Pemahaman `bind`/`unbind` krusial untuk manajemen memori dan


perilaku aplikasi yang stabil!

________

### Macam-Macam Event Handling dalam Python

Berikut adalah jenis-jenis utama event handling dalam Python,


dikelompokkan berdasarkan konteks penggunaannya:

#### 1. **GUI Event Handling** (Untuk Aplikasi Desktop/Mobile)

a. **Callback-based Binding**
- **Mekanisme**: Menghubungkan fungsi handler langsung ke event

- **Framework**: Tkinter, Kivy, PyQt

- **Contoh**:

```python

[Link]('<Button-1>', lambda event: print("Clicked!"))

```

b. **Signal-Slot Mechanism**

- **Mekanisme**: Memisahkan event (signal) dan handler (slot)

- **Framework**: PyQt/PySide

- **Contoh**:

```python

[Link](self.handle_click)

```

c. **Declarative Event Handling**

- **Mekanisme**: Mendefinisikan handler dalam deklarasi UI

- **Framework**: Kivy Lang

- **Contoh** (KV lang):

```kv

Button:

on_press: app.handle_button_press()

```

#### 2. **Asynchronous Event Handling** (I/O Bound Operations)

a. **asyncio Event Loop**

- **Mekanisme**: Menangani event I/O secara non-blocking

- **Penggunaan**: Network programming, high-performance servers

- **Contoh**:
```python

async def handle_client(reader, writer):

data = await [Link](100)

[Link](data)

```

b. **Selectors Module**

- **Mekanisme**: Multiplexing I/O events

- **Penggunaan**: Low-level socket programming

- **Contoh**:

```python

with DefaultSelector() as selector:

[Link](fileobj, EVENT_READ, callback)

```

#### 3. **System-Level Event Handling**

a. **Signal Handling**

- **Mekanisme**: Menangkap sinyal sistem (SIGINT, SIGTERM)

- **Penggunaan**: Graceful shutdown, interrupt handling

- **Contoh**:

```python

import signal

[Link]([Link], lambda s,f: print("Exit requested"))

```

b. **File System Events**

- **Mekanisme**: Memantau perubahan file/direktori

- **Library**: Watchdog, pyinotify

- **Contoh**:
```python

[Link](handler, path, recursive=True)

```

#### 4. **Custom Event Systems**

a. **Pub-Sub Pattern**

- **Mekanisme**: Decoupling publisher dan subscriber

- **Library**: PyPubSub, pydispatcher

- **Contoh**:

```python

from pubsub import pub

[Link](listener, 'data_changed')

[Link]('data_changed', data=new_data)

```

b. **Event Emitter Pattern**

- **Mekanisme**: Object-oriented event management

- **Library**: Pyee, custom implementation

- **Contoh**:

```python

[Link]('error', error_handler)

[Link]('error', Exception("Something went wrong"))

```

#### 5. **Web Event Handling**

a. **WSGI Events**

- **Mekanisme**: Request/response lifecycle

- **Framework**: Flask, Django

- **Contoh**:
```python

@[Link]('/submit', methods=['POST'])

def handle_submit():

return "Form submitted"

```

b. **WebSocket Events**

- **Mekanisme**: Real-time bidirectional communication

- **Library**: Websockets, [Link]

- **Contoh**:

```python

async def handler(websocket, path):

async for message in websocket:

await process(message)

```

### Perbandingan Karakteristik

| Jenis | Waktu Penggunaan | Kompleksitas | Performa


|

|------------------------|-----------------------------------|--------------|----------|

| GUI Callbacks | Interaksi pengguna langsung | Rendah |


Tinggi |

| Signal-Slot | Aplikasi Qt kompleks | Sedang | Tinggi |

| asyncio | I/O intensif, jaringan | Tinggi | Sangat


Tinggi |

| System Signals | Penanganan interupsi sistem | Rendah |


Tinggi |

| Pub-Sub | Komunikasi antar komponen | Sedang |


Sedang |

| Web Handlers | Aplikasi web | Variatif | Variatif |


### Best Practices

1. **GUI Applications**:

- Gunakan `on_release` bukan `on_press` untuk konfirmasi aksi

- Unbind handler saat tidak diperlukan

```python

# Kivy example

def disable_button(self):

[Link](on_press=[Link])

```

2. **Async Systems**:

- Gunakan proper task cancellation

```python

# asyncio example

task = asyncio.create_task(process_data())

[Link]() # Clean cancellation

```

3. **Error Handling**:

- Selalu tangani error di handler

```python

async def safe_handler(websocket):

try:

await handle_messages(websocket)

except ConnectionClosed:

[Link]("Connection closed")

```

4. **Resource Management**:
- Gunakan context managers untuk cleanup

```python

with watch_observer() as observer:

[Link]()

[Link]()

```

Diagram alur event handling umum:

```mermaid

sequenceDiagram

Event Source->>Event Dispatcher: Generate event

Event Dispatcher->>Event Queue: Enqueue event

Event Loop->>Event Queue: Dequeue event

Event Loop->>Handler: Dispatch event

Handler->>Response: Process event

Response-->>User: Show result

```

Pemilihan metode event handling yang tepat tergantung pada:

1. Jenis aplikasi (GUI, web, CLI)

2. Skala kompleksitas

3. Kebutuhan performa

4. Pola komunikasi antar komponen

5. Persyaratan real-time

Anda mungkin juga menyukai