ADSP-02: Pendahuluan Python untuk Data Science - Bagian Ke-02 (Fungsi)


Algorithms, Data Structures, and Programming (ADSP)
Bagian dari Combined Module: Pendahuluan High Performance (Pemrograman Parallel) for Data Science (HPDS)

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” – Martin Fowler

Bagian ke-2 dari "dasar Python" untuk Big Data & Data Science. Bagian dari modul HPDS dan ADSP di kurikulum tau-data Indonesia.
Pembahasan:

  • Menghindari copy memory di pemrograman Big Data/Data Science
  • Bagaimana Menggunakan Args dan Kwargs di fungsi Python yang bisa diaplikasikan di Machine Learning.
  • Reference to variable, fungsi lamda, dll

Video Lesson ADSP-02

adsp-02

https://tau-data.id

ADSP-02: Pendahuluan Python untuk Data Science - Bagian Ke-02


(C)Taufik Sutanto

https://tau-data.id/adsp-02

Outline Unit V:

  • Deeper with print function
  • Reference to variable(s)
  • Zipping list
  • Function

Bentuk Umum Print Function

In [1]:
# OLD Python method
nK = 7
aK = 89.234532
dt = 'klasifikasi Kanker'
print("Banyaknya kategori = %d\n dengan akurasi = %.3f\tData = '%s'" %(nK,aK,dt))

# \n ==> ganti baris .... \t = Tabulasi
# hati-hati sebelum "%(" hanya spasi (bukan koma atau titik)
# %d = digit = integer
# %f = float ... .XYZf ===> banyak digit di belakang koma = xyz
# %s = string 
Banyaknya kategori = 7
 dengan akurasi = 89.235	Data = 'klasifikasi Kanker'
In [2]:
# New Python method
nK = 7
aK = 89.234532
dt = 'klasifikasi Kanker'
print("Banyaknya kategori = {}\n dengan akurasi = {}\tData = '{}'".format(nK,aK,dt))
# perintah ".format()" pemisahnya titik
Banyaknya kategori = 7
 dengan akurasi = 89.234532	Data = 'klasifikasi Kanker'
In [3]:
# Cara memformat Floating point dengan syntax baru ini
print("Banyaknya kategori = {}\n dengan akurasi = {:.2f}\nData = '{}'".format(nK,aK,dt))
# Hati-hati agak beda dengan syntax lama untuk float ... sekarang ada tanda ":"
Banyaknya kategori = 7
 dengan akurasi = 89.23
Data = 'klasifikasi Kanker'
In [4]:
# Bisa Juga tidak terurut
a, b, c = 3, 4.5, 'xyz' # new way of initialization
print('c={2} lalu a={0}, kemudian b={1}'.format(a,b,c))
c=xyz lalu a=3, kemudian b=4.5
In [5]:
# Di Python print function kita juga bisa menspesifikasi bagaimana antar variabel dipisahkan
print(a,b,c,sep=':')
3:4.5:xyz
In [6]:
# by default setiap memanggil fungsi print Python akan pindah baris
print(a)
print(b)
print(c)
3
4.5
xyz
In [7]:
# Namun bisa dirubah
print(a, end=', ')
print(b, end=', ')
print(c, end='.')
3, 4.5, xyz.

Python - Buffer -Flush

  • Saat menjalankan proses Data Science yang cukup kompleks di Python, output print masuk ke dalam buffer dan TIDAK langsung ditampilkan.
  • Untuk memaksa print langsung ditampilkan maka parameter "flush" harus digunakan (default = False)
  • Contoh:
In [8]:
from time import sleep

for n in range(0,5):
    print("*",end='', flush = True)
    sleep(1.0)
*****

Print to File in Python

In [9]:
f = open("Output_Python.txt","w") # W = write new file, a='append existing file, new file if file does not exist'
print("ini output pertama", file=f)
f.close() # kalau tidak di close, maka bagaikan file Doc yg sedang dibuka microsoft word
# lihat di folder "notebook" akan ada file baru dengan nama file yg ditetapkan diatas
# Perhatikan perintah ini tidak mengeluarkan output langsung di notebook/terminal (silenced)
In [10]:
f = open("Output_Python.txt","w") # W = write new file, a='append existing file, new file if file does not exist'
print("ini output pertama lagi karena opennya pakai 'w'", file=f)
f.close() 
In [11]:
f = open("Output_Python.txt","a") # W = write new file, a='append existing file, new file if file does not exist'
print("ini baru output kedua karena opennya pakai 'a'", file=f)
f.close() 
# Jangan lupa utk mengingat "print" by default akan ganti baris, sehingga di akhir setiap print tidak perlu penambahan "\n"

Bagaimana membaca File Teks sudah dibahas di NLPTM-01 di Pembahasan "Menangani Slang/Singkatan"

https://tau-data.id/NLPTM-01/

Tips Penting

  • CSV sebenarnya hanya file teks yg dipisahkan dengan koma
  • TAPI hindari menulis ke file CSV dengan cara print diatas
  • Why?
In [12]:
A = [2,3,4,5,6]
print(str(A)[1:-1])
# sepertinya "ok" untuk menggunakan "trik" ini utk menulis ke CSV dari suatu list
# Misal:
2, 3, 4, 5, 6
In [13]:
Data = [ (2,56), (1,32), (5,40), (1,37), (4,40) ]

f = open("Output_Python.csv","w") 
print('Jumlah Anak, Umur', file=f)
for d in Data:
    print(str(d)[1:-1], file=f)
f.close() 

# Silahkan lihat hasilnya dan buka di NotePad/Excell
# Ndak ada masalah kan?....
# cara ini hanya cocok utk Data Terstruktur (angka atau string tapi hanya satu kata)
# Di Data Science yang sering memuat data tidak terstruktur cara ini tidak dianjurkan
# Contoh:
In [14]:
Data = [ ('@udin32','keren banget konsernya cuy!'), ('@kiraAlways','dia bilang "sa bodo", gitu katanya!'), ('@rina23','capek deeehhh...')]

f = open("Output_Python.csv","w") 
print('username, Tweet', file=f)
for d in Data:
    print(str(d)[1:-1], file=f)
f.close() 

# lihat hasilnya.
# Kalau dibuka di Notepad sepertinya tidak ada masalah
# Baru terlihat ketika di buka di excell ... benarkah???...
# Why? ... 

# Hati-hati ... karena kesalahan ini kita bisa kehilangan data berharga.
# Karena data kelak jika di import (dimanapun) akan error/tidak konsisten

Solusi

In [15]:
!pip install csv
ERROR: Could not find a version that satisfies the requirement csv (from versions: none)
ERROR: No matching distribution found for csv
In [16]:
# Gunakan saja Modul CSV/Pandas
# Karena "rule" CSV lumayan rumit 
import csv

f = open("Output_Python.csv","w", newline='') # encoding='utf-8'
f.write('Username, Tweet\n')
writer = csv.writer(f)
for d in Data:
    writer.writerow(d)
f.close()

# Lihat hasilnya di excell dan notepad

Python is not perfect, but if we know its weakness we can use it perfectly

Pointer to Reference

In [17]:
# Hati-hati dengan copy of reference (Pointer to Variabel) yg implisit di Python
A =[2,3,4]
B = A
A.append(7) # Kita tidak melakukan apa-apa ke B
print('A = ', A)
print('B = ', B)

# Mengapa outputnya seperti itu???...
# Python sebisa mungkin menghindari "copy of memory" yg cocok utk DS/ML
# menyebalkannya behavious semacam ini terkadang berbeda untuk versi python yg berbeda.
# Data Scientist perlu informasi perubahan yg terjadi ketika memakai Python versi yg lebih terbaru
# Solusi?
A =  [2, 3, 4, 7]
B =  [2, 3, 4, 7]
In [18]:
A =[2,3,4]
B = A.copy() # ini yang mirip dgn bahasa pemrograman lain B=A
A.append(7)
print('A = ', A)
print('B = ', B)
A =  [2, 3, 4, 7]
B =  [2, 3, 4]

Zipping Lists dalam data science

Akan sering ditemukan proses di DS dimana 2 buah vector/array harus di olah bersamaan pada setiap elemennya tapi dalam index yang bersesuaian.

In [19]:
# Zipping List
A = ['Minggu','Senin','Jumat', 'Selasa']
B = ['Libur', 'Kerja', 'Kerja tapi ingin Libur']

for a,b in zip(A,B):
    print('{} {}'.format(a,b))
    
# Apa yang terjadi jika listnya beda ukuran???... ==> hati-hati
# sering juga digunakan di Parallel Processing di Python ==> dibahas di PDS3
Minggu Libur
Senin Kerja
Jumat Kerja tapi ingin Libur

Tidak hanya list comprehension

In [20]:
D = {hari:kegiatan for hari, kegiatan in zip(A,B)}
D
Out[20]:
{'Minggu': 'Libur', 'Senin': 'Kerja', 'Jumat': 'Kerja tapi ingin Libur'}

DS sering memuat data dengan informasi waktu

Media Sosial, log, artikel website, sensor, etc

In [21]:
# Variabel Date-Time
from datetime import datetime
# %a %b %d %l %m %M %z %Y https://www.foragoodstrftime.com/
d1 = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
d2 = datetime.strptime('Jun 1 2004  1:33PM', '%b %d %Y %I:%M%p')
print(d1.day, d2.month, d1>d2)
1 6 True

Python Function

  • Function in Python
  • Global & local variables
  • vars, dirs**
  • Recursive function in Python
  • Lamda function
In [22]:
# Fungsi di Python cukup sederhana dan 
# parameter fungsi adalah variabel to reference
# Sebaiknya diberikan multiple lines of metaFunction (keterangan tentang fungsi)
def jumlah(A,B):
    """
    ini adalah contoh fungsi sederhana penjumlahan 2 bilangan
    input: a,b sembarang 2 bilangan (int/float)
    output: a+b
    """
    C = (A+B)+A**2
    return C # atau simply (A+B)+A**2

C = 3
D = 7
jumlah(C,D)
Out[22]:
19
In [23]:
# Kita bisa melakukan ini kalau kita membuat fungsi dengan "estetika" Python yang benar
help(jumlah)
Help on function jumlah in module __main__:

jumlah(A, B)
    ini adalah contoh fungsi sederhana penjumlahan 2 bilangan
    input: a,b sembarang 2 bilangan (int/float)
    output: a+b

In [24]:
# default Value sangat berguna di DS/ML
def jumlah(A, B=5):
    C = B+A**2
    return C

jumlah(7)
Out[24]:
54
In [25]:
def jumlah(A=3,B=5):
    C = A+B
    return C

jumlah()
Out[25]:
8
In [26]:
# Hati-hati Python bisa membuat copy variabel
def pungsi(C,D):
    return D+5

A = 10
print(pungsi(A, 2))
print(A) # tapiiii.... di dalam RAM tetap ada 2 A
7
10
In [27]:
# Solusi
# Hati-hati Python bisa membuat copy variabel
A = [7, 3, 4]
def pungsi(A,B):
    B = A # di Python B hanya pointer ke A .... sehingga tidak ada copy memory
    # ingat contoh pointer to reference di list sebelumnya
    return B

print(pungsi(A, 2))
print(A) 
[7, 3, 4]
[7, 3, 4]
In [28]:
# Contoh fungsi untuk menghitung jumlah kata di suatu status MedSos
T = 'ada apa ya pagi ini? kok macet sekali'
def wordCount(S):
    return len(S.split())

wordCount(T) 
# perhatikan saya sengaja membuat T tapi di fungsi S
# di Python S bukanlah copy memory dr T
Out[28]:
8
In [29]:
A = 3
C = 7
def pungsi(A):
    global C
    C = C*5
    return A*C

# Berguna untuk data tidak terstruktur, misal menghitung frekuensi kata di suatu corpus
print(C, pungsi(A))
print(C)
7 105
35
In [30]:
# return adalah "break" di fungsi
def f(N):
    for i in range(N):
        if i>7:
            return i
f(100)
Out[30]:
8

Apa yg terjadi di fungsi diatas ketika N = 5???

In [31]:
a = f(5)
print(a)
# Hati-hati kesalahan semacam ini di Python
None
In [32]:
# function bisa return >1 value
def F(a,b):
    return a+b, a*b

C, D = F(3,2)
print(C,D)
5 6
In [33]:
# Kalau hanya perlua satu nilai saja maka bisa lakukan hal ini (kebiasaan para programmer utk "membuang variable")
C, _ = F(3,2)
C
Out[33]:
5
In [34]:
# cara lain
C = F(3,2)[1]
C
Out[34]:
6

Map Function

In [35]:
# Sebelumnya kita punya cantoh seperti ini:
L = input('Masukkan array/List L = ')
L = L.split()
L
Masukkan array/List L = 3 6 5 9
Out[35]:
['3', '6', '5', '9']
In [36]:
# Lalu kita melakukan ini
[int(l) for l in L]
Out[36]:
[3, 6, 5, 9]
In [37]:
# Tapi ada alternatif lain dengan Map function
list( map(int, L) )
# ini lebih cepat dan efisien
Out[37]:
[3, 6, 5, 9]
In [38]:
# Contoh lain
def kuadratkan(x):
    return x*x

A = [2,3,1,6]
print( list(map(kuadratkan, A)) )
[4, 9, 1, 36]

*args and **kwargs: Flexible Arguments

  • Terkadang kita butuh untuk membuat fungsi, tapi tidak tau pasti berapa banyak parameter yang dibutuhkan.
  • *args and **kwargs digunakan pada kondisi seperti ini untuk menangkap semua parameter yang diberikan
  • parameter fungsi terkadang disebut juga arguments
  • Berikut contohnya:
In [39]:
def tangkap_parameter(*args, **kwargs):
    print("tipe args = {}, isinya = {}".format(type(args),args))
    print("tipe kwargs = {}, isinya = {}".format(type(kwargs),kwargs))
In [40]:
tangkap_parameter(1, 2, 3, a=4, b=5)
tipe args = <class 'tuple'>, isinya = (1, 2, 3)
tipe kwargs = <class 'dict'>, isinya = {'a': 4, 'b': 5}
In [41]:
tangkap_parameter('a',  keyword=2)
tipe args = <class 'tuple'>, isinya = ('a',)
tipe kwargs = <class 'dict'>, isinya = {'keyword': 2}
In [42]:
# tentu saja kita bisa juga melakukan ini
# tapi hati-hati kita butuh tanda * dan **
T = (1, 2, 3)
D = {'pi': 3.14}

tangkap_parameter(*T, **D)
tipe args = <class 'tuple'>, isinya = (1, 2, 3)
tipe kwargs = <class 'dict'>, isinya = {'pi': 3.14}

Lambdas

  • Lambda adalah "fungsi sementara"/disposable
  • Sering digunakan untuk argument/parameter di fungsi lain.
  • Dengan kata lain ada fungsi yang inputnya fungsi (lambda)
In [43]:
# Contoh sederhana
F = lambda a : a + 10
print(F(5))
15
In [44]:
# Contoh lain
x = lambda a, b, c : a + b * c
print(x(5, 6, 2))
17

Tapi mengapa tidak pakai fungsi yang biasa saja?

In [45]:
# Biasanya usecasenya seperti ini (Digunakan di perbankan)
def F(n):
  return lambda a : a * n

P = F(2)
print(P(11))
# ngerti? ... :) ... 
22
In [46]:
# Mungkin ini bisa membantu
F(2)
Out[46]:
<function __main__.F.<locals>.<lambda>(a)>
In [47]:
F(2)(11) # ini seharusnya memperjelas
Out[47]:
22
In [48]:
# Fungsi sederhana ini mengurutkan list of tuples berdasarkan elemen pertama
# di DS hal seperti ini sangat sering muncul
pairs = [(7, 'one'), (2, 'two'), (0, 'three'), (99, 'four'), (5,'afive')] # List of Tuples
pairs.sort(key=lambda p: p[0])  # nama fungsi lambdanya "key"
pairs
Out[48]:
[(0, 'three'), (2, 'two'), (5, 'afive'), (7, 'one'), (99, 'four')]

End of Modul - ADSP-02

Next Lesson ADSP-03: Struktur Data Lanjut di Python


Code Lesson ADSP-02

Code dari lesson ini dapat di akses di Link berikut (wajib login ke Google/Gmail): Code ADSP-02
Di link tersebut anda langsung bisa merubah code dan menjalankannya. Keterangan lebih lanjut di Video ADSP-02.
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.

"Side-by-Side": Ilustrasi bagaimana menggunakan code dan video dalam pembelajaran di tau-data. untuk mendapatkan pengalaman belajar yang baik.


Tidak ada komentar:

Posting Komentar

Relevant & Respectful Comments Only.