BAB IV
HASIL DAN ANALISIS
4.1Hasil Karya 4.1.1 Tampilan Form
a. Home
Gambar 4.1 Tampilan awal aplikasi
Pada saat membuka aplikasi, pengguna akan
disuguhkan tampilan awal yang sederhana. Skema adalah
nama untuk aplikasi ini, diambil dari bahasa Denmark yang
berarti skedul, rencana, atau jadwal. Tampilan awal dari
Skema terinspirasi dari desain yang sederhana dan elegan.
Di bagian pojok kanan tulisan Skema terdapat logo
yang berbentuk seperti DNA (Deoxyribonucleic Acid) dan
juga berbentuk seperti jam pasir. Dari logo Skema tersebut
dapat diambil makna bahwa DNA mewakili untuk genetika,
Jadi, dalam logo Skema menceritakan tentang sesuatu
yang dapat memproses genetika, dalam hal ini adalah
aplikasi yang melakukan proses penghitungan probabilitas
menggunakan algoritma genetika.
Gambar 4.2 Logo Skema
Di bagian bawah tulisan Skema terdapat beberapa
tombol yang digunakan untuk memanggil form yang
diinginkan. Berbeda dengan tombol pada umumnya, tombol
di aplikasi ini didesain berbentuk tautan untuk membuat
aplikasi ini terlihat sederhana tapi memiliki fitur yang
mumpuni.
b. Pelajaran
Form Pelajaran berisi tentang segala sesuatu tentang
apa yang menyangkut tentang pelajaran untuk
terselenggaranya KBM (Kegiatan Belajar Mengajar)
meliputi data mata pelajaran, data guru pengampu, data
kelas yang ada, dan plot mengajar. Plot mengajar digunakan
untuk membuat plot tentang guru pengampu mengajar
pelajaran apa dan kelas yang dimana saja guru tersebut
Gambar 4.3 Tab Mata Pelajaran dalam form Pelajaran
Pada tab Mata Pelajaran terdapat pilihan untuk
mengisi data mata pelajaran baru, mengedit atau menghapus
data mata pelajaran yang sudah ada.
Gambar 4.4 Tab guru dalam form Pelajaran
Tab Guru berisi tentang data guru, sama seperti tab
Mata Pelajaran data di tab Guru juga dapat ditambah, diedit,
maupun dihapus.
Gambar 4.5 Menu Ruang d. Jadwal
Gambar 4.6 Menu Jadwal
Pada gambar di atas dapat dilihat bahwa pada bagian
kiri terdapat 4 opsional untuk memproses jadwal.
Sedangkan dibagian kanan adalah hasil dari jadwal yang
telah diproses oleh aplikasi. 4.1.2 Pengkodean
Dari sisi pengkodean terdapat 3 garis besar untuk aplikasi ini,
yaitu pengkodean pada form untuk interaksi dengan pengguna,
pemodelan bisnis untuk transaksi data dari dan ke database,
riset dan uji coba adalah pengkodean untuk algoritma. Berikut
adalah penjelasan dari rincian di atas: 4.1.2.1 Form
Dalam pembuatan aplikasi Skema menggunakan
menggunakan OOP (Object Oriented Programming) atau
pemrograman berbasis objek, jadi setiap kelas memiliki
struktur kode yang hampir sama untuk aliran data dari
database ke form atau CRUD (Create, Read, Update, and
Delete).
Gambar 4.7 Windows form pada aplikasi Skema
Kode Program 4.3 Mengambil data pelajaran di database dalam form Pelajaran
Imports BusinessLib
Public Class Pelajaran
Private busObj As PelajaranIni = Nothing
#Region " Read "
Private Sub Pelajaran_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
busObj = New PelajaranIni
Try
Home.Cursor = Cursors.WaitCursor
dgvPmapel.DataSource = busObj.ReadMapel dgvPkelas.DataSource = busObj.ReadKelas dgvPguru.DataSource = busObj.ReadGuru dgvPlot.DataSource = busObj.ReadPlot cbPlotRefresh()
Home.Cursor = Cursors.Arrow Catch ex As Exception
MessageBox.Show(ex.Message) Home.Cursor = Cursors.Arrow End Try
Dari kode di atas dapat dilihat bahwa semua data
diambil melalui sebuah Class Library bernama
BusinessLib. Kemudian dibuatlah variabel busObj untuk
memanggil sebuah class yang bernama PelajaranIni yang
berada di dalam BusinessLib, busObj inilah yang
berfungsi untuk memanggil data dari database melalui
perantara class PelajaranIni. Data kemudian ditampung
dalam Data Grid View. Jadi setiap menu Pelajaran diklik
maka semua data dari database akan langsung dibaca dan
ditampung di Data Grid View masing-masing sub-menu.
Kode Program 4.3 Menambah data pelajaran di database dalam form Pelajaran
Imports BusinessLib
Public Class Pelajaran
Private busObj As PelajaranIni = Nothing
Private Sub btnSaveMP_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveMP.Click If rbTambah.Checked Then 'untuk membedakan tambah baru dan edit data
Try
busObj = PelajaranIni.InsertData()
'memanggil fungsi insert data, dan mengisi value _newdata menjadi true ditambahkan", "Sukses", MessageBoxButtons.OK,
Di dalam kode program di atas mengunakan
fungsi if dan else, jadi apabila Radio Button diklik untuk
tambah data maka fungsi if akan berjalan dan langsung
melakukan proses penambahan data melalui class
PelajaranIni yang berada dalam class library BusinessLib.
Begitu pula dengan mengedit data, apabila Radio Button
diklik edit data maka fungsi else yang gantian berjalan
dan melakukan proses edit data melalui alur yang sama
(melewati BusinessLib).
Kode Program 4.3 Mengedit data pelajaran di database dalam form Pelajaran
Apabila kita perhatikan baris kode di atas dapat
dilihat bahwa untuk proses edit, data diambil dahulu
kemudian baru menyimpan perubahan ke dalam database. Else 'berisi id yg terpilih dari dgv
With busObj
"Sukses", MessageBoxButtons.OK,
Agar data yang baru ditambah atau diedit langsung
terbaca maka akan dilakukan refresh di DataGridView
setiap kali data berhasil diproses.
Kemudian yang terakhir mengenani transaksi data
dari form adalah hapus data. Kode untuk menghapus data
cukup sederhana dan tidak terlalu rumit untuk dibuat.
Kode Program 4.4 Menghapus data pelajaran di database dalam form Pelajaran
MessageBox pertama berfungsi untuk memberikan peringatan kepada
user agar tidak salah saat menghapus data yang telah
dipilih. Setelah selesai proses menghapus maka akan ada
Private Sub HapusToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles
HapusToolStripMenuItem.Click pilihan.Row(2).ToString 'inisialisasi id sebagai patokan
MessageBox.Show("Anda yakin ingin mengapus mata pelajaran " + namaMapel, "Hapus data?",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) pelajaran " + namaMapel + " berhasil dihapus :D",
"Sukses", MessageBoxButtons.OK,
PublicClass Utilities
PublicSharedFunction koneksi()
Return ("data source=TOSHIBATKJ-01\sqlEXPRESS ; database = skemadb; integrated security=SSPI")
EndFunction EndClass
informasi bahwa data tersebut telah dihapus dan
DataGridView akan refresh lagi untuk memperbarui data. 4.1.2.2Basis Data
Dalam pengkodean basis data digunakan Class
Library yang berfungsi agar class ini nantinya dapat
di-reference ke class lainnya yang membutuhkan transaksi
data dari database. BusinessLib memiliki beberapa class
yang berfungsi untuk melayani transaksi data dari setiap
form yang berbeda, misal class PelajaranIni berfungsi
untuk melayani transaksi data dari form Pelajaran.
Gambar 4.8 Class pada BusinessLib
Dalam class di atas terdapat kelas bernama
Utilities yang berfungsi untuk menginisialisasikan
koneksi ke Database Engine yaitu SQL SERVER 2008
agar tidak dipanggil berulang kali saat ingin membuka
koneksi.
Kode Program 4.5 Class Utilities
Setelah terhubung ke database dengan memanggil fungsi
Public Function ReadMapel() As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection(Utilities.koneksi) Try
dasar yang biasa dipakai untuk mengambil data.
Kode Program 4.6 Mengambil data dari database
Data yang telah diambil dari database ditampung
di Data Table. Hal ini dilakukan agar memudahkan saat
ditampilkan di DataGridView pada form.
Untuk menambahkan data ke database diperlukan
fungsi yang dapat diakses oleh semua class dikarenakan
'shared method
Public Shared Function InsertData() As PelajaranIni
Dim obj As New PelajaranIni Select Case _pilihan Case "mapel".ToLower
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@kdmp", _kodeMapel) cm.Parameters.AddWithValue("@nmmp", _namaMapel) cm.ExecuteNonQuery()
Kode Program 4.7 Menambah data ke database
Menambahkan data ke database dibutuhkan
variabel yang berfungsi untuk menampung data dari form
yang telah dimasukkan oleh user. Kemudian variabel
tersebut dijadikan untuk mengisi value agar dapat terbaca
di query sebagai parameter yang sebelumnya
didefinisikan sebagai alias, misal @kdmp, @nmmp,
'shared method
Public Shared Function UpdateData(id As Integer) As
PelajaranIni
Dim obj As New PelajaranIni 'jadi si id ini langsung menginput ke semua variabel
obj.MapelID = id 'nanti si pilihan yang ngecek obj.GuruID = id 'si id itu masuk ke pilihan mana Select Case _pilihan Case "mapel".ToLower
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@mpid", _mapelID) cm.Parameters.AddWithValue("@kdmp", _kodeMapel) cm.Parameters.AddWithValue("@nmmp", _namaMapel) cm.ExecuteNonQuery()
Public Shared Function DeleteData(id As Integer) As
PelajaranIni
qry = "SELECT * FROM PlotMengajar WHERE MapelID=@mpid"
Using cn As New SqlConnection(Utilities.koneksi) Try
Seperti pada saat menambah data, mengedit data
juga mengunakan fungsi shared method dan juga instance
method untuk prosesnya. Yang jadi pembeda adalah pada
fungsi shared method berisi value yang berasal dari form
dan tentunya query dalam data portal.
Kode Program 4.8 Mengedit data dari database
...
Private Sub DeleteMapel() Dim qry As String
If _isThere Then
qry="DELETE FROM PlotMengajar Where MapelId=@mpid;"& _ "DELETE FROM Mapel Where MapelId = @mpid;"
Else
qry = "DELETE FROM Mapel Where MapelId = @mpid;"
End If
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@mpid", _mapelID) cm.ExecuteNonQuery()
End Using
Catch ex As Exception
_isThere = True Call DeleteMapel() Finally
Dalam proses hapus, data terlebih dahulu dicek
punya relasi dengan dengan tabel PlotMengajar atau tidak,
kalau data tersebut mempunyai relasi maka digunakanlah
query yang pertama (fungsi if) yaitu menghapus terlebih
dahulu id mata pelajaran di tabel PlotMengajar kemudian
baru menghapus data yang ada di tabel Mapel. Apabila
data yang ingin dihapus tidak mempunyai relasi, maka
digunakanlah query kedua (fungsi else) untuk menghapus
data di tabel Mapel.
4.1.2.3Algoritma Genetika
Dalam algoritma genetika harus digunakan
beberapa variabel acak untuk proses optimasi. Skema
memiliki fituruntuk memberikan nilai acak tersebut untuk
proses penghitungan optimasi tersebut. Variabel Jumlah
gen dan Populasi per generasi menggunakan bilangan asli,
untuk menentukannya tergantung dari banyaknya data.
Oleh karena itu secara default Jumlah Gene diberi nilai
100 agar semua data di PlotMengajar dapat ditampung.
Sedangkan untuk Populasi per generasi diberi nilai default
mengganti variabel disarankan untuk memasukkan nilai
yang lebih besar dari nilai sebelumnya, karena pada saat
proses penghitungan optimasi dengan nilai yang kecil
sering terjadi overload data atau data tidak dapat diproses
lebih lanjut karena kurangnya sampel data.
Kemudian untuk variabel probabilitas crossover
dan probabilitas mutasi tidak harus diganti, akan tetapi
apabila menginginkan hasil yang lebih bervarisasi maka
dapat diganti sesuai keinginan. Nilai untuk variabel
tersebut mempunyai rentan antara 0 sampai 1, dan tidak
boleh bernilai 0 dan atau 1. Secara default nilai variabel
untuk Probabilitas crossover dan Probabilitas mutasi
masing-masing 0.5 dan 0.1, angka tersebut diperoleh dari
hasil trial and error pada saat proses development aplikasi
Skema.
Gambar 4.9 Variabel dalam form Jadwal
Jadi fitur variabel sangat membantu untuk
pun tidak terlalu dipusingkan oleh pengisian variabel
karena tingkat kesalahan pemilihan variabel tersebut
sudah diperhitungkan sebelumnya. Kesalahan dapat
terjadi apabila variabel Jumlah Gen di form lebih sedikit
dibanding variabel gen yang ada di Class Library
Algoritma. Variabel gen ini didapat dari array 2 dimensi
yang berisi data jumlah mata pelajaran, data ruang, dan
data waktu.
Pseudo code 4.1. Algoritma Genetika
Kode Program 4.10 Inisialisasi awal
Inisialisasi Populasi
Sampai mendapat individu yg diinginkan dari generasi yg
ditetapkan
Dim qry As String = "SELECT COUNT(*) FROM PlotMengajar"
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
Kode Program 4.11 Proses algoritma genetika (garis besar)
Kode Program 4.12 Evaluasi populasi 'inisialisasi populasi ag = New AG
ag.GenetikAI(jumlahKromosom, mataPelajaran, guruMP, ruang, waktu, probCrossover, probMutasi) ganti parameter di atas", MsgBoxStyle.Critical, "Failed") Exit Sub
End If
Public Sub hitungFitness() Call hitungGuruBentrok() Call hitungRuanganBentrok()
_fitness = 1.0F / (1.0F + _tabrakanG + _tabrakanR) End Sub
Public Sub hitungGuruBentrok()
'guru yg sama mengajar di kelas berbeda dalam satu waktu _tabrakanG = 0
Dim _isFinish As Boolean = False _indexSkip = New List(Of Integer) For i As Integer = 0 To _jumlahGen - 1
_isFinish = False
If Not _indexSkip.Contains(i) Then
For j As Integer = i + 1 To _jumlahGen - 1 If Not _indexSkip.Contains(j) Then
Kode Program 4.13 Seleksi kromosom
Public Sub seleksi() _totalFitness = 0.0F
'cari total fitness semua kromosom
For i As Integer = 0 To _jumlahKromosom - 1
_totalFitness = _totalFitness + _kromosom(i)._fitness Next
_kromosom(i)._kumulatifMax = _kromosom(i - 1)._kumulatifMax + _kromosom(i)._probabilitasFitness End If
Next
'kumulatif itu pas kromosom dijumlahkan terus dibagi lagi dengan angka yang sama
Dim r As Random = New Random
_randomSeleksi = New Double(_jumlahKromosom - 1) {}
Kode Program 4.14 Crossover (bagian pertama)
Public Sub crossover() Dim r As New Random
_randomCrossover = New Double(_jumlahKromosom - 1) {} _crossoverTerpilih = New List(Of Integer)
For i As Integer = 0 To _jumlahKromosom - 1 _randomCrossover(i) = r.NextDouble()
If _randomCrossover(i) <= _probabilitasCrossover Then _crossoverTerpilih.Add(i)
End If Next
If _crossoverTerpilih.Count >= 2 Then Dim r2 As New Random
Dim titik As Integer = r2.Next(0, _kromosom(0)._jumlahGen - 1)
Dim temp() As Integer = New Integer(2) {}
For i As Integer = 0 To _crossoverTerpilih.Count - 1 For j As Integer = i + 1 To _crossoverTerpilih.Count - 1 Dim sebelum1 As StringBuilder = New StringBuilder
Dim sebelum2 As StringBuilder = New StringBuilder
Dim sesudah1 As StringBuilder = New StringBuilder
Dim sesudah2 As StringBuilder = New StringBuilder
For k As Integer = 0 To 3 'jumlah sebelum dan sesudah
For x As Integer = titik To _kromosom(0)._jumlahGen - 1 temp(0) = _kromosom(_crossoverTerpilih(i))._gen(x, 0) temp(1) = _kromosom(_crossoverTerpilih(i))._gen(x, 1) temp(2) = _kromosom(_crossoverTerpilih(i))._gen(x, 2)
Kode Program 4.15 Crossover (bagian kedua)
_randomMutasi = New Double(_jumlahKromosom * _kromosom(0)._jumlahGen - 1) {}
For i As Integer = 0 To _randomMutasi.Length - 1 _randomMutasi(i) = r3.NextDouble()
If _randomMutasi(i) < _probabilitasMutasi Then
Dim row, column As Integer
row = Math.Floor(i / _kromosom(0)._jumlahGen) column = i Mod _kromosom(0)._jumlahGen
Dim index As Integer
index = _waktu.IndexOf(_kromosom(row)._gen(column, 2))
If index = _waktu.Count - 1 Then index = 0
End If
_kromosom(row)._gen(column, 2) = _waktu(index + 1) End If
Kode Program 4.17 Populasi baru (apabila ditemukan)
4.2Hasil Pengujian 4.2.1 Inisialisasi Awal
Inisialisasi awal bertujuan untuk menghimpun data-data dari
database yang berhubungan dengan proses Algoritma Genetika
yaitu membuat gen. Dalam inisialisasi awal dibutuhkan variabel
berbentuk array dan list of array yang berfungsi untuk
menampung parameter dan atau value yang diambil dari
database.
Public Function cekTerbaik() Dim optimal As Integer = -1 Dim maksimal As Integer = 0 Dim isTerbaik As Boolean = False
For i As Integer = 0 To _jumlahKromosom - 1 If _kromosom(maksimal)._fitness < _kromosom(i)._fitness Then
maksimal = i End If
If _kromosom(maksimal)._fitness = 1 Then optimal = maksimal
Exit For End If
Next
If Not optimal = -1 Then
_kromosomTerbaik = _kromosom(optimal) isTerbaik = True
Else
_kromosomTerbaik = _kromosom(maksimal) isTerbaik = False
End If
Return isTerbaik End Function
Gambar 4.10 Array value dalam variabel mataPelajaran 4.2.2 Inisialisasi Algoritma Genetika
Setelah mendapatkan beberapa value dari inisialisasi awal,
hal berikutnya adalah membuat kromosom. Variabel Populasi per
gen menentukan jumlah kromosom yang dibuat, semakin tinggi
nilai variabelnya semakin banyak pula jumlah kromosom yang
diciptakan.
Pada gambar di atas dapat terlihat bahwa variabel kromosom
memiliki nilai list of array 10 karena parameter yang diberikan
untuk Populasi per generasi pada form adalah 10. Pada
masing-masing list of array terdapat variabel gen yang berfungsi untuk
menampung nilai gen yang terbentuk dari data mata pelajaran,
guru pengampu, ruang, dan waktu dalam bentuk array. 4.2.3 Hitung Fitness
Pada hitung fitness, setiap kromosom akan dihitung satu
persatu nilai fitnessnya. Apabila fitness bernilai mendekati 1 atau
nilainya 1 maka kromosom pada indeks itulah yang akan dipilih.
Gambar 4.12 Nilai fitness pada salah satu kromosom
Untuk menghitung fitness perlu dihitung terlebih dahulu
nilai variabel pendukungnya. Sub class hitungGuruBentrok dan
hitungRuanganBentrok berfungsi untuk mengidentifikasi berapa
value untuk variabel _tabrakanG untuk guru dan _tabrakanR
untuk ruang. Jadi gambaran sederhananya kalau pada gen di
dalam kromosom ada yang sama akan mengurangi nilai
variabelnya. Dalam hal ini diasumsikan apabila ada guru yang
sama mengajar di kelas berbeda dalam satu waktu maka akan
terjadi bentrokan, begitu pula pada ruangan.
Variabel _fitness bertipe single, karena dengan tipe data
single nilai didapatkan bisa utuh. Berbeda dengan tipe data
decimal yang sangat presisi pada setiap perhitungnya, tipe data
membuatnya lebih cepat memproses perhitungan. Sebagai
perbandingan saat membagi angka 1 dengan 3 kemudian dikali
lagi 3 maka hasilnya adalah 0.9999 kalau menggunakan tipe data
decimal, tapi menghasilkan nilai 1 apabila menggunakan tipe data
single. Maka dari itu dipilihlah tipe data single untuk menghitung
fitness yang bernilai angka desimal yang banyak. Akan tetapi tipe
data ini tidak disarankan untuk perhitungan matematika karena
hanya mempunyai panjang 16 bit.
Gambar 4.13 Salah satu kromosom yang nilai fitnessnya 1
4.2.4 Seleksi
Setelah mendapat kromosom dengan nilai fitness 1 proses
belum selesai, karena biasanya yang memiliki nilai fitness 1 tidak
Pada proses seleksi ada beberapa tahapan yaitu mencari
nilai total fitness semua kromosom, mencari probabilitas
masing-masing fitness pada setiap kromosom, mencari nilai kumulatif
masing-masing fitness pada setiap kromosom, dan yang terakhir
memilih kromosom yang lolos seleksi.
Gambar 4.14 Kromosom yang telah terseleksi 4.2.5 Crossover / Kawin Silang
Crossover atau bisa juga disebut kawin silang berfungsi
untuk meng-crossover kromosom-kromosom dari hasil seleksi
sehingga menghasilkan individu baru. Pada praktiknya,
melakukan crossover tidaklah mudah. Sebelum di-crossover
variabel terlebih dahulu dimasukkan ke dalam variabel bertipe
string builder. Tipe data string builder dipilih karena ada banyak
looping yang berisi banyak value. Value dari setiap variabel
tersebut kemudian digunakan untuk mengisi parameter dari
variabel dengan nama sebelum1 dan sebelum2 yang nantinya
akan di-crossover. Kelebihan dari tipe data string builder adalah
bagian belakang untuk kemudian dijadikan bahan untuk
melakukan crossover.
Gambar 4.15 Value sebelum crossover (string builder data type)
Gambar 4.16 Value sesudah crossover (string builder data type) 4.2.6 Mutasi
Mutasi digunakan untuk mendapatkan hasil tidak terduga
dari suatu solusi (salah satu atau beberapa value dalam
kromosom) dengan cara merubah value dari gen secara acak yang
membuat gen tersebut berevolusi. Solusi itu memberikan nilai
yang berbeda untuk fungsi fitness. Mutasi hanya merubah suatu
kromosom, dan tidak berpengaruh kepada kromosom yang
Gambar 4.17 Gen dari kromosom yang telah bermutasi 4.2.7 Cek Fitness Terbaik
Setelah melalui banyak proses seperti yang telah dijelaskan,
algoritma genetika masih mempunyai satu proses terakhir
sebelum mencapai hasil. Kromosom dari populasi yang telah
dibuat dicari nilai fitness yang paling tinggi. Jadi semua
kromosom dicari nilai fitnessnya, dengan begitu didapatlah
kromosom yang mempunyai nilai fitness tertinggi. Apabila dalam
sebuah populasi tidak menemukan kromosom terbaik, maka akan
dilakukan proses ulang dari awal pembentukan gen sampai cek
Gambar 4.18 Kromosom terbaik ditemukan 4.2.8 Hasil
Hasil akan langsung ditampilkan pada DataGridView di samping
menu variabel, dengan begitu jadwal langsung dapat lihat.
Apabila data tidak ditampilkan maka tinggal klik tombol proses
dan aplikasi akan meng-generate hasil yang lainnya.
Gambar 4.16 Hasil Jadwal
4.3Analisa Sistem
Setelah melalui proses yang panjang dan rumit, aplikasi
berhasil mencapai tujuan utam yaitu menghasilkan jadwal tanpa
adanya tabrakan. Dari hasil pengujian diatas dapat diketahui
bahwa semua data telah dimasukkan dan telah diproses
Akan tetapi dapat terlihat masih ada beberapa bug yang
sebenarnya tidak terlalu fatal akan tetapi tetap harus ada
perbaikan untuk versi selanjutnya. Karena maintenance harus
selalu dilakukan agar aplikasi yang dibuat mempunyai bug