Lewati ke konten utama

Data Class Python: Tutorial Komprehensif

Tutorial ramah pemula tentang data class Python dan cara menggunakannya dalam praktik
Diperbarui 5 Jun 2026  · 9 mnt baca

Data class adalah salah satu fitur Python yang, setelah Anda menemukannya, Anda tidak akan kembali ke cara lama. Pertimbangkan kelas biasa berikut:

class Exercise:
   def __init__(self, name, reps, sets, weight):
       self.name = name
       self.reps = reps
       self.sets = sets
       self.weight = weight

Bagi saya, definisi kelas itu sangat tidak efisien — di metode __init__, Anda mengulang setiap parameter setidaknya tiga kali. Ini mungkin terdengar sepele, tetapi pikirkan seberapa sering Anda menulis kelas seumur hidup dengan parameter yang jauh lebih banyak.

Sebagai perbandingan, lihat alternatif data class dari kode di atas:

from dataclasses import dataclass


@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float  # Weight in lbs

Potongan kode yang tampak sederhana ini jauh lebih baik daripada kelas biasa. Dekorator kecil @dataclass mengimplementasikan kelas __init__, __repr__, __eq__ di balik layar, yang jika ditulis manual akan memakan setidaknya 20 baris kode.

Selain itu, banyak fitur lain seperti operator perbandingan, pengurutan objek, dan imutabilitas, semuanya hanya berjarak satu baris untuk tercipta secara “ajaib” bagi kelas kita.

Jadi, tujuan tutorial ini adalah menunjukkan mengapa data class adalah salah satu hal terbaik yang terjadi pada Python jika Anda menyukai pemrograman berorientasi objek.

Mari kita mulai!

Dasar-dasar Data Class Python

Mari bahas beberapa konsep mendasar dari data class Python yang membuatnya begitu berguna.

Beberapa metode dihasilkan secara otomatis dalam data class

Meski penuh fitur, data class adalah kelas biasa yang membutuhkan jauh lebih sedikit kode untuk mengimplementasikan fungsionalitas yang sama. Ini kelas Exercise lagi:

from dataclasses import dataclass


@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float


ex1 = Exercise("Bench press", 10, 3, 52.5)

# Verifying Exercise is a regular class
ex1.name
'Bench press'

Saat ini, Exercise sudah memiliki metode __repr__ dan __eq__ yang terimplementasi. Mari kita verifikasi:

repr(ex1)
"Exercise(name='Bench press', reps=10, sets=3, weight=52.5)"

Representasi objek oleh repr harus mengembalikan kode yang dapat merekreasinya, dan kita bisa lihat itulah yang terjadi pada ex1.

Sebagai perbandingan, Exercise yang didefinisikan dengan cara lama akan terlihat seperti ini:

class Exercise:
   def __init__(self, name, reps, sets, weight):
       self.name = name
       self.reps = reps
       self.sets = sets
       self.weight = weight


ex3 = Exercise("Bench press", 10, 3, 52.5)

ex3
<__main__.Exercise at 0x7f6834100130>

Terlihat buruk dan tidak berguna!

Sekarang, mari verifikasi keberadaan __eq__, yaitu operator kesetaraan:

# Redefine the class
@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float


ex1 = Exercise("Bench press", 10, 3, 52.5)
ex2 = Exercise("Bench press", 10, 3, 52.5)

Membandingkan kelas dengan dirinya sendiri dan dengan kelas lain yang parameternya identik harus menghasilkan True:

ex1 == ex2
True
ex1 == ex1
True

Dan memang begitu! Dalam kelas biasa, logika ini akan merepotkan untuk ditulis.

Data class memerlukan type hint

Seperti yang mungkin Anda perhatikan, data class memerlukan type hint saat mendefinisikan field. Faktanya, data class mengizinkan tipe apa pun dari modul typing. Misalnya, berikut cara membuat field yang dapat menerima tipe data Any:

from typing import Any


@dataclass
class Dummy:
   attr: Any

Namun, keunikan Python adalah meskipun data class memerlukan type hint, tipe tersebut sebenarnya tidak dipaksakan.

Sebagai contoh, membuat instance kelas Exercise dengan tipe data yang sama sekali tidak benar tetap dapat dijalankan tanpa error:

silly_exercise = Exercise("Bench press", "ten", "three sets", 52.5)

silly_exercise.sets

“Three sets”

Jika Anda ingin memaksa tipe data, Anda harus menggunakan type checker seperti Mypy.

Data class memungkinkan nilai default pada field

Sejauh ini, kita belum menambahkan nilai default pada kelas kita. Mari kita perbaiki:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0


# Now, all fields have defaults
ex5 = Exercise()
ex5
Exercise(name='Push-ups', reps=10, sets=3, weight=0)

Ingat bahwa field non-default tidak boleh berada setelah field default. Misalnya, kode di bawah ini akan melempar error:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float  # NOT ALLOWED


ex5 = Exercise()
ex5
TypeError: non-default argument 'weight' follows default argument

Dalam praktiknya, Anda jarang mendefinisikan default dengan sintaks name: type = value.

Sebagai gantinya, Anda akan menggunakan fungsi field yang memberi kontrol lebih pada setiap definisi field:

from dataclasses import field


@dataclass
class Exercise:
   name: str = field(default="Push-up")
   reps: int = field(default=10)
   sets: int = field(default=3)
   weight: float = field(default=0)


# Now, all fields have defaults
ex5 = Exercise()
ex5
Exercise(name='Push-up', reps=10, sets=3, weight=0)

Fungsi field memiliki lebih banyak parameter, seperti:

  • repr
  • init
  • compare
  • default_factory

dan seterusnya. Kita akan membahas ini di bagian berikutnya.

Data class dapat dibuat dengan fungsi

Catatan terakhir tentang dasar data class adalah bahwa definisinya bisa lebih singkat lagi dengan menggunakan fungsi make_dataclass:

from dataclasses import make_dataclass

Exercise = make_dataclass(
   "Exercise",
   [
       ("name", str),
       ("reps", int),
       ("sets", int),
       ("weight", float),
   ],
)

ex3 = Exercise("Deadlifts", 8, 3, 69.0)
ex3
Exercise(name='Deadlifts', reps=8, sets=3, weight=69.0)

Namun Anda akan mengorbankan keterbacaan, jadi saya tidak menyarankan menggunakan fungsi ini.

Data Class Python Lanjutan

Di bagian ini, kita akan membahas fitur-fitur lanjutan data class yang memberikan lebih banyak manfaat. Salah satunya adalah default factory.

Default factory

Untuk menjelaskan default factory, mari buat kelas lain bernama WorkoutSession yang menerima dua field:

from dataclasses import dataclass
from typing import List


@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0


@dataclass
class WorkoutSession:
   exercises: List[Exercise]
   duration_minutes: int

Dengan menggunakan tipe List, kita menyatakan bahwa WorkoutSession menerima daftar instance Exercise.

# Define the Exercise instances for HIIT training
ex1 = Exercise(name="Burpees", reps=15, sets=3)
ex2 = Exercise(name="Mountain Climbers", reps=20, sets=3)
ex3 = Exercise(name="Jump Squats", reps=12, sets=3)
exercises_monday = [ex1, ex2, ex3]

hiit_monday = WorkoutSession(exercises=exercises_monday, duration_minutes=30)

Saat ini, setiap instance sesi latihan memerlukan exercises untuk diinisialisasi. Namun ini tidak mencerminkan cara orang berolahraga — pertama, mereka memulai sesi (mungkin di aplikasi), lalu menambahkan latihan seiring berjalannya waktu.

Jadi, kita harus bisa membuat sesi tanpa latihan dan tanpa durasi. Mari wujudkan ini dengan menambahkan daftar kosong sebagai nilai default untuk exercises:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = []
   duration_minutes: int = None


hiit_monday = WorkoutSession("25-02-2024")
ValueError: mutable default <class 'list'> for field exercises is not allowed: use default_factory

Namun, kita mendapat error — ternyata data class tidak mengizinkan nilai default yang mutable.

Untungnya, kita bisa memperbaikinya dengan menggunakan default factory:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=list)  # PAY ATTENTION
   duration_minutes: int = 0


hiit_monday = WorkoutSession()
hiit_monday
WorkoutSession(exercises=[], duration_minutes=0)

Parameter default_factory menerima fungsi yang mengembalikan nilai awal untuk field data class. Artinya, ia dapat menerima fungsi apa pun:

  • tuple
  • dict
  • set
  • Fungsi kustom buatan pengguna apa pun

Ini berlaku terlepas dari apakah hasil fungsi tersebut mutable atau tidak.

Sekarang, jika dipikir-pikir, kebanyakan orang memulai latihan dengan pemanasan yang biasanya serupa untuk jenis latihan apa pun. Jadi, menginisialisasi sesi tanpa latihan mungkin bukan yang diinginkan sebagian orang.

Sebagai gantinya, mari buat fungsi yang mengembalikan tiga Exercise pemanasan:

def create_warmup():
   return [
       Exercise("Jumping jacks", 30, 1),
       Exercise("Squat lunges", 10, 2),
       Exercise("High jumps", 20, 1),
   ]

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5  # Increase the default duration as well


hiit_monday = WorkoutSession()
hiit_monday

WorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), Exercise(name='Squat lunges', reps=10, sets=2, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0)], duration_minutes=5)

Sekarang, setiap kali kita membuat sesi, sesi tersebut akan memuat beberapa latihan pemanasan yang sudah tercatat. Versi baru WorkoutSession memiliki durasi default lima menit untuk mengakomodasi hal itu.

Menambahkan metode ke data class

Karena data class adalah kelas biasa, menambahkan metode ke dalamnya tetap sama. Mari tambahkan dua metode ke data class WorkoutSession kita:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   def add_exercise(self, exercise: Exercise):
       self.exercises.append(exercise)

   def increase_duration(self, minutes: int):
       self.duration_minutes += minutes

Dengan menggunakan metode-metode ini, sekarang kita dapat mencatat aktivitas baru ke sebuah sesi:

hiit_monday = WorkoutSession()

# Log a new exercise
new_exercise = Exercise("Deadlifts", 6, 4, 60)

hiit_monday.add_exercise(new_exercise)
hiit_monday.increase_duration(15)

Tetapi ada masalah:

hiit_monday

WorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), Exercise(name='Squat lunges', reps=10, sets=2, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0), Exercise(name='Deadlifts', reps=6, sets=4, weight=60)], duration_minutes=20)

Saat kita mencetak sesi, representasi default-nya terlalu verbose dan sulit dibaca karena berisi kode untuk merekreasikan objek. Mari kita perbaiki.

__repr__ dan __str__ dalam data class

Data class mengimplementasikan __repr__ secara otomatis tetapi tidak __str__. Ini membuat kelas menggunakan __repr__ ketika kita memanggil print pada objek tersebut.

Jadi, mari timpa perilaku ini dengan mendefinisikan __str__ sendiri:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0

   def __str__(self):
       base = f"{self.name}: {self.reps}/{self.sets}"
       if self.weight == 0:
           return base
       return base + f", {self.weight} lbs"


ex1 = Exercise(name="Burpees", reps=15, sets=3)
ex1
Exercise(name='Burpees', reps=15, sets=3, weight=0)

__repr__ masih sama, tetapi ketika kita memanggil print:

print(ex1)
Burpees: 15/3

Representasi string kelas jauh lebih enak dibaca. Sekarang, mari perbaiki WorkoutSession juga:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5  # Increase the default duration as well

   def add_exercise(self, exercise: Exercise):
       self.exercises.append(exercise)

   def increase_duration(self, minutes: int):
       self.duration_minutes += minutes

   def __str__(self):
       base = ""

       for ex in self.exercises:
           base += str(ex) + "\n"
       base += f"\nSession duration: {self.duration_minutes} minutes."

       return base


hiit_monday = WorkoutSession()
print(hiit_monday)

Jumping jacks: 30/1
Squat lunges: 10/2
High jumps: 20/1

Session duration: 5 minutes.

Catatan: Gunakan tombol “Explain code” di bagian bawah cuplikan untuk mendapatkan penjelasan kode baris demi baris.

Sekarang, kita mendapatkan keluaran yang ringkas dan mudah dibaca.

Perbandingan dalam data class

Untuk banyak kelas, masuk akal untuk membandingkan objeknya dengan suatu logika. Untuk latihan, ini bisa berupa durasi latihan, intensitas, atau beban.

Pertama, mari lihat apa yang terjadi jika kita mencoba membandingkan dua sesi latihan dalam keadaan saat ini:

hiit_wednesday = WorkoutSession()

hiit_wednesday.add_exercise(Exercise("Pull-ups", 7, 3))
print(hiit_wednesday)

Jumping jacks: 30/1
Squat lunges: 10/2
High jumps: 20/1
Pull-ups: 7/3

Session duration: 5 minutes.

hiit_monday > hiit_wednesday
TypeError: '>' not supported between instances of 'WorkoutSession' and 'WorkoutSession'

Kita menerima TypeError karena data class tidak mengimplementasikan operator perbandingan. Namun ini mudah diperbaiki dengan menyetel parameter order ke True:

@dataclass(order=True)
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession()
# hiit_monday.add_exercise(...)
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession()

hiit_monday > hiit_wednesday

True

Kali ini, perbandingan berhasil, tetapi apa yang sebenarnya kita bandingkan?

Dalam data class, perbandingan dilakukan sesuai urutan field didefinisikan. Saat ini, kelas dibandingkan berdasarkan durasi latihan karena field pertama, exercises, berisi objek non-standar.

Kita bisa memverifikasi ini dengan menambah durasi sesi hari Rabu:

hiit_monday = WorkoutSession()
# hiit_monday.add_exercise(...)

hiit_wednesday = WorkoutSession()
hiit_wednesday.increase_duration(10)

hiit_monday > hiit_wednesday
False

Sesuai dugaan, kita menerima False.

Namun apa yang terjadi jika field pertama Workout adalah tipe lain, misalnya string? Mari kita coba:

@dataclass(order=True)
class WorkoutSession:
   date: str = None  # DD-MM-YYYY
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession("25-02-2024")
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession("27-02-2024")

hiit_monday > hiit_wednesday
False

Meskipun sesi Senin berlangsung lebih lama, perbandingan menunjukkan bahwa sesi tersebut lebih kecil daripada Rabu. Alasannya adalah “25” datang sebelum “27” dalam perbandingan string Python.

Jadi, bagaimana kita mempertahankan urutan field dan tetap mengurutkan sesi berdasarkan durasi latihan? Ini mudah melalui fungsi field:

@dataclass(order=True)
class WorkoutSession:
   date: str = field(default=None, compare=False)
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession("25-02-2024")
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession("27-02-2024")

hiit_monday > hiit_wednesday
True

Dengan menyetel compare ke False untuk field apa pun, kita mengecualikannya dari pengurutan, seperti yang dibuktikan oleh hasil di atas.

Manipulasi field pasca-inisialisasi

Saat ini, kita memiliki durasi sesi default lima menit untuk mengakomodasi latihan pemanasan. Namun, ini hanya masuk akal jika pengguna memulai sesi dengan pemanasan. Bagaimana jika mereka memulai sesi dengan latihan lain:

new_session = WorkoutSession([Exercise("Diamond push-ups", 10, 3)])

new_session.duration_minutes
5

Untuk satu latihan saja, total durasi lima menit terasa tidak masuk akal. Setiap sesi harus secara dinamis memperkirakan durasinya berdasarkan jumlah set dari tiap latihan. Artinya kita harus membuat duration_minutes bergantung pada field exercises.

Mari kita implementasikan:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = field(default=0, init=False)

   def __post_init__(self):
       set_duration = 3
       for ex in self.exercises:
           self.duration_minutes += ex.sets * set_duration

   ...

Kali ini, kita mendefinisikan duration_minutes dengan init disetel ke False untuk menunda inisialisasi field.

Lalu, di dalam metode khusus __post_init__, kita memperbarui nilainya berdasarkan total jumlah set di setiap Exercise.

Sekarang, ketika kita menginisialisasi WorkoutSession, duration_minutes secara dinamis bertambah tiga menit untuk setiap set di tiap latihan.

# Adding an exercise with three sets
hiit_friday = WorkoutSession([Exercise("Diamond push-ups", 10, 3)])

hiit_friday.duration_minutes
9

Secara umum, jika Anda ingin mendefinisikan field yang bergantung pada field lain dari data class Anda, Anda dapat menggunakan logika __post_init__.

Imutabilitas dalam Data Class

Data class WorkoutSession kita hampir siap; tinggal perlu dilindungi. Saat ini, kelas ini mudah sekali diutak-atik:

hiit_friday.duration_minutes = 1000

hiit_friday.duration_minutes
1000

del hiit_friday.exercises

Kita ingin melindungi semua field kelas kita agar hanya bisa dimodifikasi dengan cara yang kita inginkan. Untuk mencapai ini, dekorator @dataclass menawarkan argumen frozen yang praktis:

@dataclass(frozen=True)
class FrozenExercise:
   name: str
   reps: int
   sets: int
   weight: int | float = 0


ex1 = FrozenExercise("Muscle-ups", 5, 3)

Sekarang, jika kita ingin mengubah field apa pun, kita mendapat error:

ex1.sets = 5
FrozenInstanceError: cannot assign to field 'sets'

Menyetel frozen ke True secara otomatis menambahkan metode __deleteattr__ dan __setattr__ untuk setiap field sehingga terlindung dari penghapusan atau pembaruan setelah inisialisasi. Juga, orang lain tidak akan bisa menambahkan field baru:

ex1.new_field = 10
FrozenInstanceError: cannot assign to field 'new_field'

Fungsionalitas ini akan membutuhkan puluhan baris kode jika kita menggunakan kelas tradisional.

Namun, perlu dicatat bahwa kita tidak bisa membuat kelas benar-benar immutable. Misalnya, mari tulis ulang WorkoutSession dengan frozen disetel ke True:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


session1 = ImmutableWorkoutSession()

Seperti yang diharapkan, kita tidak bisa langsung memodifikasi daftar latihan:

session1.exercises = [Exercise()]

Namun, exercises adalah daftar, yang sepenuhnya mutable, sehingga operasi berikut memungkinkan:

# Mengubah salah satu elemen dalam daftar

# Changing one of the elements in a list
session1.exercises[1] = FrozenExercise("Totally new exercise", 5, 5)

print(session1)

ImmutableWorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), FrozenExercise(name='Totally new exercise', reps=5, sets=5, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0)], duration_minutes=5)

Jadi, untuk melindungi dari perubahan yang tidak disengaja, disarankan menggunakan objek immutable seperti tuple untuk nilai field.

Pewarisan dalam data class

Satu poin terakhir yang akan kita bahas adalah urutan field di kelas induk dan turunan.

Karena data class adalah kelas biasa, pewarisan berjalan seperti biasa:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


@dataclass(frozen=True)
class CardioWorkoutSession(ImmutableWorkoutSession):
   pass

Namun, karena field terakhir di kelas induk (ImmutableWorkoutSession) memiliki nilai default, semua field di kelas turunan harus memiliki nilai default.

Sebagai contoh, ini tidak diizinkan:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


@dataclass(frozen=True)
class CardioWorkoutSession(ImmutableWorkoutSession):
   intensity_level: str  # Not allowed, must have a default

TypeError: non-default argument 'intensity_level' follows default argument

Kekurangan Data Class dan Sumber Lanjutan

Data class terus meningkat sejak Python 3.7 (sejak awal pun sudah bagus) dan mencakup banyak kasus penggunaan saat Anda perlu menulis kelas. Namun, data class bisa kurang menguntungkan dalam skenario berikut:

  • Metode __init__ kustom
  • Metode __new__ kustom
  • Beragam pola pewarisan

Dan banyak lagi, seperti dibahas dalam thread Reddit yang bagus ini. Jika Anda menginginkan alasan lebih rinci mengapa data class diperkenalkan dan mengapa mereka bukan pengganti langsung definisi kelas biasa, bacalah PEP 557.

Jika Anda tertarik pada pemrograman berorientasi objek secara umum, berikut kursus untuk melanjutkan perjalanan Anda:

Pada dasarnya, data class adalah struktur yang lebih canggih untuk menyimpan dan mengambil data dengan lebih efisien. Namun, Python memiliki banyak struktur data lain yang melakukan tugas ini dengan cara yang kurang lebih serupa. Misalnya, Anda dapat mempelajari counter, defaultdict, dan namedtuple di bab terakhir dari kursus Data Types for Data Science.


Bex Tuychiev's photo
Author
Bex Tuychiev
LinkedIn

Saya adalah pembuat konten ilmu data dengan pengalaman lebih dari 2 tahun dan salah satu dengan jumlah pengikut terbesar di Medium. Saya suka menulis artikel mendetail tentang AI dan ML dengan sedikit gaya sarkastik karena harus ada sesuatu untuk membuatnya sedikit kurang membosankan. Saya telah menghasilkan lebih dari 130 artikel dan satu kursus DataCamp, dengan satu lagi sedang dalam proses. Konten saya telah dilihat oleh lebih dari 5 juta pasang mata, dengan 20 ribu di antaranya menjadi pengikut di Medium dan LinkedIn. 

Topik

Terus Belajar Python

Program

Dasar-Dasar Data Python

28 Hr
Kembangkan keterampilan data Anda, pelajari cara mengolah dan memvisualisasikan data, serta terapkan analisis canggih untuk mengambil keputusan berbasis data.
Lihat DetailRight Arrow
Mulai Kursus
Lihat Lebih BanyakRight Arrow
Terkait

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

Lihat Lebih BanyakLihat Lebih Banyak