Algorithms, Data Structures, and Programming (ADSP)
Bagian dari Combined Module: Pendahuluan High Performance (Pemrograman Parallel) for Data Science (HPDS)
Bagian ke-4 dari "dasar Python" untuk Big Data & Data Science. Bagian dari modul HPDS dan ADSP di kurikulum tau-data Indonesia.
Pembahasan Pendahuluan OOP di Python bagian ke-01:
- Class
- Init
- Method & Properties
Video Lesson ADSP-04
Algorithms, Data Structures, and Programming (ADSP)
https://taudata.blogspot.com/2020/04/adsp-04.html
ADSP-04: Pendahuluan OOP di Python
(C) Taufik Sutanto
Reading material: https://www.python-course.eu/python3_object_oriented_programming.php¶
Paradigma Pemrograman
- Cited from Van Roy, “Programming Paradigms for Dummies,” page 13, figure 2, see https://www.info.ucl.ac.be/~pvr/VanRoyChapter.pdf
- Baca keterangan lebih lanjut disini: https://taudata.blogspot.com/2020/04/dsbd-05.html
Definisi¶
class: a class describes the contents of the objects that belong to it: it describes an aggregate of data fields (called instance variables), and defines the operations (called methods).
object: an object is an element (or instance) of a class; objects have the behaviors of their class.
https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora140.html
Sebelum OOP - Procedural Programming Paradigm¶
# Contoh PP
def f1(x):
return x**2 + 1
def f2(x, h=10**-3):
return (f1(x+h)-f1(x))/h
f1(5), f2(3)
(26, 6.000999999999479)
Kelemahan PP?¶
image source: https://medium.com/@1550707241489/procedural-programming-vs-object-oriented-programming-7d541a62f5c¶
- Saat fungsi sudah terlalu banyak perubahan kecil di suatu fungsi akan menyebabkan seluruh code tidak berjalan dengan baik. Karena keterbegantungan antar fungsi begitu tinggi.
- Untuk program sederhana tidak terlalu masalah.
Perlukah Data Scientist Belajar OOP
- Beginner-Intermediate .... IMHO No.
- Advanced, research, atau corporate ... Yes!.
N = 99
T = 'sembarang string'
print(type(N), type(T))
<class 'int'> <class 'str'>
(Hampir) Semua hal di Python adalah object, termasuk fungsi kita sebelumnya¶
print(type(f1))
<class 'function'>
Karena object, maka ia memiliki properties dan fungsi¶
print( T.split() ) # Fungsi/method objek string T
N.real # Property ditandai dengan tidak adanya tanda "()"
# di Python Property di sebut Attribute
['sembarang', 'string']
99
import numpy as np
A = np.array([1,2,3])
dir(A)
['T', '__abs__', '__add__', '__and__', '__array__', '__array_finalize__', '__array_function__', '__array_interface__', '__array_prepare__', '__array_priority__', '__array_struct__', '__array_ufunc__', '__array_wrap__', '__bool__', '__class__', '__complex__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__iand__', '__ifloordiv__', '__ilshift__', '__imatmul__', '__imod__', '__imul__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'all', 'any', 'argmax', 'argmin', 'argpartition', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'ctypes', 'cumprod', 'cumsum', 'data', 'diagonal', 'dot', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'partition', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view']
# Tentu saja ini akan Error, tapi perhatikan pesan error-nya.
try:
N.split()
except Exception as err_:
print('Error : ', err_)
Error : 'int' object has no attribute 'split'
Secara umum ada beberapa konsep dalam sistem OOP¶
image Source: https://www.nerd.vision/post/polymorphism-encapsulation-data-abstraction-and-inheritance-in-object-oriented-programming¶
Tapi bagaimana kalau mau membuat sendiri object-nya?¶
# Contoh di http://python-course.eu disini tidak perlu if-main
class Robot:
pass
x = Robot()
y = Robot()
y2 = y
print(y == y2)
print(y == x)
True False
# Bad practice, tapi dapat dilakukan di Python
# Menambahkan property ke object
x.name = "Marvin"
x.build_year = "1979"
y.name = "Caliban"
y.build_year = "1993"
f1.keterangan ='contoh pungsi pertama' #bahkan fungsi adalah object
print(x, x.name, y.build_year, x.__dict__, f1.keterangan, sep='\n')
<__main__.Robot object at 0x000002797163A780> Marvin 1993 {'name': 'Marvin', 'build_year': '1979'} contoh pungsi pertama
# Menambahkan fungsi ke Object
class Robot: # sebagai pembeda Class biasanya diawali huruf besar
def beriSalam(self): # Method
print('Assalamualaikum')
gundam = Robot()
print(type(gundam))
# __main__ ==> dimana "robot" kita di definisikan.
# Defaultnya di __main__
<class '__main__.Robot'>
# Kita sudah definisikan sebelumnya "Robot" punya method "beriSalam"
gundam.beriSalam()
Assalamualaikum
# Tentu saja object juga bisa "return" values
class Robot:
def sapa(self, nama = ''):
return "Hi " + nama
def beriSalam(self): # Method
print('Assalamualaikum')
gundam = Robot()
x = gundam.sapa('taudata')
x
'Hi taudata'
Apa itu "self" ? ... Sebelumnya mari kita bahas dulu "init"¶
class Robot:
# __init__ akan dijalankan setiap Objek dibuat
def __init__(self, tipe, tahun=2020):
self.tipe = tipe
self.tahun_produksi = tahun
def sapa(self, nama = ''):
return "Hi " + nama
def beriSalam(self): # Method
print('_Assalamualaikum_ ... :)')
Android17 = Robot('dbz', tahun=1997) # __init__ dijalankan disini
Android18 = Robot('dbz') # __init__ dijalankan disini
Gundam = Robot('SuperNova', tahun=2020)
# Apa yang dimasukkan ke tanda () akan dimasukkan ke "fungsi __init__"
Android17.tipe, Android18.tipe, Gundam.tahun_produksi
('dbz', 'dbz', 2020)
Gundam.tahun_produksi
2020
class Robot:
# __init__ akan dijalankan setiap Objek dibuat
def __init__(self, tipe, tahun=2020):
self.tipe = tipe
self.tahun_produksi = tahun
def sapa(self, nama = ''):
return "Hi " + nama
def beriSalam(self): # Method
print('_Assalamualaikum_ ... :)')
def getDetails(self):
return self.tipe, self.tahun_produksi
Android18 = Robot('dbz', 2002) # __init__ dijalankan disini
Android18.getDetails(), Android18.tipe
(('dbz', 2002), 'dbz')
# Perhatikan pesan error berikut untuk lebih mengerti tentang self
class Robot:
# __init__ akan dijalankan setiap Objek dibuat
def __init__(self, tipe, tahun=2020):
self.tipe = tipe
self.tahun_produksi = tahun
def sapa(self, nama = ''):
return "Hi " + nama
def beriSalam(self): # Method
print('_Assalamualaikum_ ... :)')
def getDetails():
return self.tipe, self.tahun_produksi
Android18 = Robot('dbz', 2002) # __init__ dijalankan disini
try:
Android18.getDetails()
except Exception as err_:
print('Error : ', err_)
# self adalah parameter input by default ... walau ndak nampak/explicitly given
Error : getDetails() takes 0 positional arguments but 1 was given
queue = []
queue.append(3)
queue.append(4)
queue.append(7)
queue.pop()
queue
[3, 4]
L = [1, 2, 3]
S = {1, 2, 3}
L.append(4); S.add(4)
L, S
([1, 2, 3, 4], {1, 2, 3, 4})
class Robot:
# __init__ akan dijalankan setiap Objek dibuat
def __init__(self, tipe, tahun=2020):
self.tipe = tipe
self.tahun_produksi = tahun
def sapa(self, nama = ''):
return "Hi " + nama
def beriSalam(self): # Method
print('_Assalamualaikum_ ... :)')
def getDetails(self):
return self.tipe, self.tahun_produksi
def gantiTipe(self, tipe):
self.tipe = tipe
Android18 = Robot('dbz', 2002) # __init__ dijalankan disini
Android18.gantiTipe('DB GT')
Android18.getDetails()
('DB GT', 2002)
Tapi kenapa pakai objek?¶
Kenapa tidak (misal):¶
- Nama = ['Android17', 'Android18', 'Gundam']
- tahun_produksi = [1997, 1998, 1999]
- tipe = ['dbz', 'dbz', 'superNova']
Karena:
- indexing-nya can be messy.
- Attribute dan atau Method bisa berbeda.
- Panjang list/array bisa berbeda (mirip JSON) ==> Note: json pada dasarnya mirip object.
Tapi kita akan coba contoh yg lebih kompleks agar lebih memahami tentang OOP¶
class Mahasiswa:
def __init__(self, nama, nilai):
self.nama = nama
self.nilai = nilai
def nilai_mahasiswa(self):
return self.nilai
class Kuliah:
def __init__(self, nama, max_mahasiswa):
self.nama = nama
self.max_mahasiswa = max_mahasiswa
self.mahasiswa = []
def tambah_mahasiswa(self, nama):
if len(self.mahasiswa) < self.max_mahasiswa:
self.mahasiswa.append(nama)
return True
else:
return "Error: Maaf kelas Penuh"
m1 = Mahasiswa('Udin', 77)
m2 = Mahasiswa('Ucok', 67)
m3 = Mahasiswa('Asep', 87)
kelas = Kuliah('Kalkulus', 2)
kelas.tambah_mahasiswa(m1), kelas.tambah_mahasiswa(m2)
(True, True)
kelas.mahasiswa
[<__main__.Mahasiswa at 0x23ee55a08b0>, <__main__.Mahasiswa at 0x23ee55a0640>]
kelas.tambah_mahasiswa(m3)
'Error: Maaf kelas Penuh'
# Akses mahasiswa di "kelas"?
kelas.mahasiswa
# List of Objects!
# tapi kemudian
[<__main__.Mahasiswa at 0x279716387f0>, <__main__.Mahasiswa at 0x27971638748>]
kelas.mahasiswa[0].nama
# karena elemen list adalah object ....
'Udin'
# Tambah fungsi rata-rata nilai kelas
class Mahasiswa:
def __init__(self, nama, nilai):
self.nama = nama
self.nilai = nilai
def nilai_mahasiswa(self):
return self.nilai
class Kuliah:
def __init__(self, nama, max_mahasiswa):
self.nama = nama
self.max_mahasiswa = max_mahasiswa
self.mahasiswa = []
def tambah_mahasiswa(self, nama):
if len(self.mahasiswa) < self.max_mahasiswa:
self.mahasiswa.append(nama)
return True
else:
return "Error: Maaf kelas Penuh"
def rerata_nilai(self):
sum_ = 0
for siswa in self.mahasiswa:
sum_ += siswa.nilai_mahasiswa()
# perhatikan disini kita melakukan ini karena siswa adalah objek
# objek siswa punya methode "nilai_mahasiswa"
return sum_/len(self.mahasiswa)
m1 = Mahasiswa('Udin', 77)
m2 = Mahasiswa('Ucok', 67)
m3 = Mahasiswa('Asep', 87)
kelas = Kuliah('Kalkulus', 2)
kelas.tambah_mahasiswa(m1), kelas.tambah_mahasiswa(m2)
(True, True)
'Nilai rata-rata kelas ', kelas.nama, ' adalah = ', kelas.rerata_nilai()
('Nilai rata-rata kelas ', 'Kalkulus', ' adalah = ', 72.0)
Perhatikan dengan konsep OOP¶
- Tidak peduli banyak mahasiswa/kelas/cara menghitung nilai jadi lebih mudah dalam organize code-nya.
Di kuliah berikutnya kita akan membahas "Inheritance"¶
image source: https://www.edureka.co/blog/object-oriented-programming-python/¶
End of Module
Code Lesson ADSP-04
Code dari lesson ini dapat di akses di Link berikut (wajib login ke Google/Gmail): Code ADSP-04
Di link tersebut anda langsung bisa merubah code dan menjalankannya. Keterangan lebih lanjut di video yang disertakan.
Sangat disarankan untuk membuka code dan video "side-by-side" untuk mendapatkan pengalaman belajar yang baik. SIlahkan modifikasi (coba-coba) hal lain, selain yang ditunjukkan di video untuk mendapatkan pengalaman belajar yang lebih mendalam. Tentu saja juga silahkan akses berbagai referensi lain untuk memperkaya pengetahuan lalu diskusikan di forum yang telah disediakan.
Tidak ada komentar:
Posting Komentar
Relevant & Respectful Comments Only.