Archive

Archive for November, 2010

Mengurutkan Bilangan pada Array menggunakan Algoritma Merge Sort

November 23, 2010 1 comment

Algoritma lain yang menggunakan Divide and Conquer dalam pengurutan adalah Merge Sort.

Secara   konseptual,  untuk  sebuah array  berukuran  n,
Merge Sort bekerja sebagai berikut:
1.  Jika  bernilai  0   atau   1,   maka  array  sudah   terurut.

2.   Jika Array tidak terurut, bagi menjadi 2 sub-array dengan ukuran n/2

3. Urutkan setiap sub array. Jika sub array tidak cukup kecil lakukan langkah kedua dengan rekursif

4. Menggabungkan sub array menjadi satu array

Berikut ini implementasi sederhana dari Algoritma Merge Sort dengan C++ dan Tool yang digunakan Code Block 8.02

#include <iostream>

using namespace std;
void merge(int low, int mid, int up);
void mergeSort(int low, int up);
int a[50];
int main()
{
int jumlahBil,i;
cout<<"Masukkan Jumlah element Array"<< endl;
cin>>jumlahBil;
for(int i=0; i<jumlahBil;i++)
{
cout<<"Bilangan ke-"<< i+1 << endl;
cin>>a[i];
}
mergeSort(1,jumlahBil);
for(i=1;i<=jumlahBil;i++)
cout<<a[i]<<"    ";
cout<<endl;
return 0;
}
void merge(int low, int mid, int up)
{
int h, i,j,k;
int b[50];
h = low;
i = low;
j = mid+1;
while((h<=mid)&&(j<=up))
{
if(a[h] < a[j])
{
b[i]=a[h];
h++;
}
else
{
b[i]=a[j];
j++;
}
i++;
}
if(h>mid)
{
for(k=j;k<=up;k++){
b[i]=a[k];
i++;
}
}
else
{
for(k=h;k<=mid;k++)
{
b[i]=a[k];
i++;
}
}
for(k=low;k<=up;k++) a[k]=b[k];
}
void mergeSort(int low, int up)
{

int mid;
if(low<up)
{
mid=(low+up)/2;
mergeSort(low,mid);
mergeSort(mid+1,up);
merge(low,mid,up);
}
}

Advertisements

Mengurutkan Bilangan pada Array menggunakan Algoritma Quick Sort

November 21, 2010 Leave a comment

Salah satu algoritma yang menggunakan paradigma Divide and Conquer adalah Algoritma Quick  Sort. Algoritma ini mengambil salah satu elemen secara acak (biasanya dari tengah) yang disebut dengan pivot  lalu menyimpan semua elemen yang lebih kecil di sebelah kiri pivot  dan semua elemen yang lebih besar di sebelah kanan pivot. Hal ini dilakukan secara rekursif terhadap elemen di sebelah kiri dan kanannya sampai semua elemen sudah terurut.

Ide dari algoritma ini adalah sebagai berikut:

a. Pilih satu elemen secara acak sebagai pivot

b. Pindahka semua elemen yang lebih kecil ke sebelah kiri pivot dan semua elemen yang lebih besar ke sebelah kanan pivot. Elemen yang nilainya sama bisa disimpan di salah satunya.

c. Lakukan sort secara rekursif terhadap sub-array sebelah kiri dan kanan pivot

Berikut ini implementasi Algoritma Quick Sort menggunakan C++ dengan Tool yang digunakan Code Block 8.02

#include <iostream>
#define n 20

using namespace std;
int Ar[n];
void quickSort(int arr[], int left, int right);

int main()
{   int jumlahBil=5;

cout<<"Masukkan jumlah bilangan dalam arry [Maksimal 20]"<<endl;
cin>>jumlahBil;
int Ar[jumlahBil];
for(int i=0; i<jumlahBil;i++)
{
cout<<"Bilangan ke-"<< i+1 << endl;
cin>>Ar[i];
}
quickSort(Ar,0,jumlahBil-1 );
cout<<"Data yang telah diurutkan"<<endl;
for(int i=0; i<jumlahBil;i++)
{
cout<<Ar[i]<<"\n";
}

}
void quickSort(int arr[], int left, int right)
{
int i = left, j = right;

int tmp;

int pivot = arr[(left + right) / 2];
while (i <= j) {

while (arr[i] < pivot)

i++;

while (arr[j] > pivot)

j--;

if (i <= j) {
tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

i++;

j--;

}

};

if (left < j)

quickSort(arr, left, j);

if (i < right)

quickSort(arr, i, right);
}

Semoga membantu 😀

Jika salah tolong koreksi saya.

Referensi : dari berbagai sumber

Aplikasi Kalkulator dengan Java

November 20, 2010 3 comments

Pada kesempatan kali ini, kita akan membuat aplikasi sederhana kalkulator dengan menggunakan Java. Tool yang digunakan dalam membuat aplikasi kalkulator adalah Netbeans 6.9.

Berikut ini tampilan aplikasi yang akan kita buat.

Aplikasi Kalkulator dengan Java

Tampilan Aplikasi Kalkulator

Langkah dalam membuat aplikasi tersebut.

  • Buat design program seperti gambar tersebut dengan NetBeans. Design tersebut terdiri dari 16 JButton dan 1 JTextField
  • Ubah nama variabel dan nama text pada setiap JButton dan JTextField. Misal button angka satu saya ganti nama variabelnya dengan btSatu dan seterusnya. Untuk JTextField nama variabel saya ubah dengan tfLayar.
  • Buat variabel berikut pada JFrame.

String angka;
double total, bilanganSatu, bilanganDua;    int pilihan;

  • Buat event method untuk setiap JButton yang ada

misal untuk btSatu, tambahkan method sebagai berikut.

private void btSatuActionPerformed(java.awt.event.ActionEvent evt) {
angka+=”1″;
tfLayar.setText(angka);
}

dan tambahkan method yang sama untuk btDua – btSembilan.

untuk btKurang tambahkan method berikut.

private void btTambahActionPerformed(java.awt.event.ActionEvent evt) {
bilanganSatu = Double.parseDouble(angka);
tfLayar.setText(“+”);
angka =””;
pilihan =2;
}

untuk btTambah.

private void btTambahActionPerformed(java.awt.event.ActionEvent evt) {
bilanganSatu = Double.parseDouble(angka);
tfLayar.setText(“+”);
angka =””;
pilihan =2;
}

untuk btBagi.

private void btBagiActionPerformed(java.awt.event.ActionEvent evt) {
bilanganSatu = Double.parseDouble(angka);
tfLayar.setText(“/”);
angka =””;
pilihan =1;
}

untuk btKali

private void btKaliActionPerformed(java.awt.event.ActionEvent evt) {
bilanganSatu = Double.parseDouble(angka);
tfLayar.setText(“*”);
angka =””;
pilihan =4;
}

untuk btSama

private void btSamaActionPerformed(java.awt.event.ActionEvent evt) {
switch(pilihan){
case 1:
bilanganDua = Double.parseDouble(angka);
total = bilanganSatu / bilanganDua;
angka = Double.toString(total);
tfLayar.setText(angka);
break;
case 2:
bilanganDua = Double.parseDouble(angka);
total = bilanganSatu + bilanganDua;
angka = Double.toString(total);
tfLayar.setText(angka);
break;
case 3:
bilanganDua = Double.parseDouble(angka);
total = bilanganSatu – bilanganDua;
angka = Double.toString(total);
tfLayar.setText(angka);
break;
case 4:
bilanganDua = Double.parseDouble(angka);
total = bilanganSatu * bilanganDua;
angka = Double.toString(total);
tfLayar.setText(angka);
break;
default:
break;

}
}

untuk btClear

private void btClearActionPerformed(java.awt.event.ActionEvent evt) {
tfLayar.setText(“”);
bilanganSatu = 0;
bilanganDua  = 0;
total = 0;
angka =””;
}

Berikut ini Link download untuk source code program diatas.

Semoga membantu 😀

Binary Tree dengan C++

November 18, 2010 2 comments

Salah satu jenis struktur data yang cukup populer adalah Binary Tree atau Pohon Biner. Menurut saya Binary Tree mempunyai kemampuan / efisiensi yang sama baik dengan binary search dalam hal searching. Tapi lebih baik dalam hal insert, delete dan traversal daripada binary search. Karena alokasi memory dari Binary Tree dinamis sedangkan alokasi binary search statis karena menggunakan array. Agar suatu struktur data tree dapat disebut dengan Binary Tree harus dipenuhi syarat sebagai berikut :

  • Setiap node / impul maksimal mempunyai dua sub-node
  • Nilai pada node sebelah kiri lebih kecil dari pada node disebelah kanan

Berikut ini code untuk Binary Tree dalam bahasa C++ dengan tool yang digunakan CodeBlock 8.02

#include <iostream>
#include <cstdlib>
using namespace std;

class BinarySearchTree
{
private:
struct nodeTree
{
nodeTree* left;
nodeTree* right;
int data;
};
nodeTree* root;

public:
BinarySearchTree()
{
root = NULL;
}

bool isEmpty() const { return root==NULL; }
void print_inorder();
void inorder(nodeTree*);
void print_preorder();
void preorder(nodeTree*);
void print_postorder();
void postorder(nodeTree*);
void insert(int);
void remove(int);
};

void BinarySearchTree::insert(int d)
{
nodeTree* t = new nodeTree;
nodeTree* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;

if(isEmpty()) root = t;
else
{

nodeTree* current;
current = root;

while(current)
{
parent = current;
if(t->data > current->data) current = current->right;
else current = current->left;
}

if(t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}

void BinarySearchTree::remove(int d)
{
//Locate the element
bool found = false;
if(isEmpty())
{
cout<<" This Tree is empty! "<<endl;
return;
}

nodeTree* current;
nodeTree* parent;
current = root;

while(current != NULL)
{
if(current->data == d)
{
found = true;
break;
}
else
{
parent = current;
if(d>current->data) current = current->right;
else current = current->left;
}
}
if(!found)
{
cout<<" Data not found! "<<endl;
return;
}

// Node dengan single child
if((current->left == NULL && current->right != NULL)|| (current->left != NULL
&& current->right == NULL))
{
if(current->left == NULL && current->right != NULL)
{
if(parent->left == current)
{
parent->left = current->right;
delete current;
}
else
{
parent->right = current->right;
delete current;
}
}
else
{
if(parent->left == current)
{
parent->left = current->left;
delete current;
}
else
{
parent->right = current->left;
delete current;
}
}
return;
}

// node tidak mempunyai child node
if( current->left == NULL && current->right == NULL)
{
if(parent->left == current ) parent->left = NULL;
else parent->right = NULL;
delete current;
return;
}

//Node dengan 2 child node
// ganti node dengan nilai terkecil di subtree bagain kanan
if (current->left != NULL && current->right != NULL)
{
nodeTree* temp;
temp = current->right;
if((temp->left == NULL) && (temp->right == NULL))
{
current = temp;
delete temp;
current->right = NULL;
}
else
{

if((current->right)->left != NULL)
{
nodeTree* lcurrent;
nodeTree* lcurrp;
lcurrp = current->right;
lcurrent = (current->right)->left;
while(lcurrent->left != NULL)
{
lcurrp = lcurrent;
lcurrent = lcurrent->left;
}
current->data = lcurrent->data;
delete lcurrent;
lcurrp->left = NULL;
}
else
{
nodeTree* tmp2;
tmp2 = current->right;
current->data = tmp2->data;
current->right = tmp2->right;
delete tmp2;
}

}
return;
}

}

void BinarySearchTree::print_inorder()
{
inorder(root);
}

void BinarySearchTree::inorder(nodeTree* p)
{
if(p != NULL)
{
if(p->left) inorder(p->left);
cout<<" "<<p->data<<" ";
if(p->right) inorder(p->right);
}
else return;
}

void BinarySearchTree::print_preorder()
{
preorder(root);
}

void BinarySearchTree::preorder(nodeTree* p)
{
if(p != NULL)
{
cout<<" "<<p->data<<" ";
if(p->left) preorder(p->left);
if(p->right) preorder(p->right);
}
else return;
}

void BinarySearchTree::print_postorder()
{
postorder(root);
}

void BinarySearchTree::postorder(nodeTree* p)
{
if(p != NULL)
{
if(p->left) postorder(p->left);
if(p->right) postorder(p->right);
cout<<" "<<p->data<<" ";
}
else return;
}

int main()
{
BinarySearchTree b;
int ch,tmp,tmp1;
while(1)
{
cout<<endl<<endl;
cout<<" Binary Search Tree Operations "<<endl;
cout<<" ----------------------------- "<<endl;
cout<<" 1. Insertion/Creation "<<endl;
cout<<" 2. In-Order Traversal "<<endl;
cout<<" 3. Pre-Order Traversal "<<endl;
cout<<" 4. Post-Order Traversal "<<endl;
cout<<" 5. Removal "<<endl;
cout<<" 6. Exit "<<endl;
cout<<" Enter your choice : ";
cin>>ch;
switch(ch)
{
case 1 : cout<<" Enter Number to be inserted : ";
cin>>tmp;
b.insert(tmp);
break;
case 2 : cout<<endl;
cout<<" In-Order Traversal "<<endl;
cout<<" -------------------"<<endl;
b.print_inorder();
break;
case 3 : cout<<endl;
cout<<" Pre-Order Traversal "<<endl;
cout<<" -------------------"<<endl;
b.print_preorder();
break;
case 4 : cout<<endl;
cout<<" Post-Order Traversal "<<endl;
cout<<" --------------------"<<endl;
b.print_postorder();
break;
case 5 : cout<<" Enter data to be deleted : ";
cin>>tmp1;
b.remove(tmp1);
break;
case 6 :
return 0;

}
}
}

dengan referensi dari berbagai sumber. baik kode maupun materi tentang Binary Tree

Semoga membantu 😀

Binary Search dengan C++

November 17, 2010 Leave a comment

Pencarian Biner (Binary Search) dilakukan untuk :

  • memperkecil jumlah operasi pembandingan yang harus dilakukan antara data yang dicari dengan data yang ada di dalam tabel, khususnya untuk jumlah data yang sangat besar ukurannya.
  • Prinsip dasarnya adalah melakukan proses pembagian ruang pencarian secara berulang-ulang sampai data ditemukan atau sampai ruang pencarian tidak dapat dibagi lagi (berarti ada kemungkinan data tidak ditemukan).
  • Syarat utama untuk pencarian biner adalah data di dalam tabel harus sudah terurut, misalkan terurut menaik.

Berikut ini code binary search dengan bahasa C++ dan tool yang digunakan Turbo C++

#include<iostream.h>
#include<conio.h>
#include<stdio.h>

void binSearch(int cari);
void main(){
clrscr();
int searchValue=20; /*Nilai yang dicari dalam arry yang sudah terurut */
binSearch(searchValue);
getch();

}
void binSearch(int cari)
{ int lb=1, ub=19, mid; /* lb merupakan batas bawah, up merupakan batas atas */
int nilai [20] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int jumlahPerbandingan =1; /* Optional */
mid= (lb+ub)/2;

while( nilai[mid]!= cari && lb<=ub)
{
jumlahPerbandingan++;
if( nilai [mid] > cari )
{ub = mid-1;}
else
{lb = mid +1;}
mid = (lb+ub)/2;
}

if(lb<=ub)
{
cout << “Nilai berhasil ditemukan”;
cout<<“Jumlah perbandingan :”<<jumlahPerbandingan;
}
else
cout <<“Nilai tidak ditemukan”;
}

Catatan :

Array bersifat statis baik nilai maupun jumlah element telah ditentukan sejak awal program.

Semoga bermanfaat.

Jika salah koreksi saya.

Terima Kasih 😀

Exception Handling dalam Java

November 16, 2010 Leave a comment

Exception merupakan kondisi yang menyebabkan program menjadi hang atau quit dari alur normal yang telah ditentukan pada saat program dijalankan. Exception ini dipicu oleh Runtime Error, yaitu error yang terjadi saat program dieksekusi. Pada dasarnya Exception merupakan sub class dari kelas Throwable, kelas ini terdapat pada package java.lang.object yang merupakan default library dari java. Class Exception mempunyai beberapa sub class yaitu

  • ClassNotFoundException, terjadi bila kita menggunakan class yang tidak ada
  • CloneNotSupportedException, terjadi bila kita mencoba untuk menggandakan suatu class yang tidak didukung oleh method clone
  • RuntimeException
  • ArithmeticException, khusus untuk menangani kesalahan pada operasi aritmatika seperti pembagian dengan nol
  • IOException, terjadi bila ada I/O error

Dalam menangani exception terdapat 5 keyword penting dalam java.

  • Bagian pertama adalah keyword try, catch dan finally

keyword try digunakan pada suatu blok program yang diperkirakan blok tersebut terjadi exception. keyword try harus dipasangkan dengan keyword catch, keyword catch tersebut digunakan untuk menangkap dan memproses bila terjadi exception. sedangkan finally ini merupakan keyword yang menunjukan bahwa blok program tersebut akan selalu dieksekusi meskipun adanya kesalahan yang muncul atau pun tidak ada, keyword ini bersifat optional semacam default pada switch-case.

Berikut ini contoh yang saya ambil dari JENI bab exception

main.java

public static void main(String[] args ) {
try{

int a = Integer.parseInt(args[1]);
System.out.println(5/a);
}
catch(ArithmeticException e)
{
System.out.println(“Pembagian dengan nol”);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(“Missing argument”);
}
}

untuk mengetahui perbedaan antar exception yang digunakan, ubah parameter pada method Integer.parseInt(“0”);

  • Bagian kedua adalah throw

pernyataan throw digunakan untuk melempar exception secara eksplisit. Pertama kita harus mendapatkan penanganan dalam suatu instance throwable, melalui suatu parameter kedalam bagian catch, atau dengan membuatnya menggunakan operator new. Bentuk umum pernyataan throw :

throw ThrowableInstance;
Aliran eksekusi akan segera terhenti setelah pernyataan throw, dan pernyataan selanjutnya tidak akan dicapai. Blok try terdekat akan diperiksa untuk melihat jika telah memiliki bagian catch yang cocok dengan tipe instance Throwable. Jika tidak ditemukan yang cocok, maka pengaturan dipindahkan ke pernyataan tersebut. Jika tidak, maka blok pernyataan try selanjutnya diperiksa, begitu seterusnya sampai penanganan eksepsi terluar menghentikan program dan mencetak penelusuran semua tumpukan sampai pernyataan throw.
main.java
public class Main { 

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String input =”Invalid Input”;
try{
if(input.equals(“Invalid Input”))
{
throw new RuntimeException(“Throw Demo”);
}
else {
System.out.println(input);
}
}
catch (RuntimeException e){
System.out.println(“Exception diproses disini”);
System.out.println(e);
}
}
}

  • Bagian ketiga adalah throws

Kata kunci throws digunakan untuk mengenali daftar eksepsi yang mungkin di-throw oleh suatu method. Jika tipe eksepsinya adalah error, atau RuntimeException, atau suatu subclassnya, aturan ini tidak berlaku, karena tidak diharapkan sebagai bagian normal dari kerja program.Jika suatu method secara eksplisit men-throws suatu intans dari Exception atau subclassnya, diluar RuntimeException, kita harus mendeklarasikan tipenya dengan pernyataan throws. ini mendefinisikan ulang deklarasi method sebelumnya dengan sintaks sebagai berikut :

type method-name (arg-list) throws exception-list {}

{

method body.

}

contoh.

ThrowingClass.java

class ThrowingClass {
static void myMethod() throws ClassNotFoundException {
throw new ClassNotFoundException (“just a demo”);
}
}

Main.java

class Main {
public static void main(String args[]) {
try {
ThrowingClass.myMethod();
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
}

Note.

berdasar beberapa sumber yang saya baca throws bisa digunakan untuk class. tapi saya belum mencobanya.

Semoga membantu

Kalau salah koreksi saya.

Terima Kasih

Takdir Allah SWT

November 14, 2010 Leave a comment

Mendapat aritikel yang menarik dari www.eramuslim.com Semoga bermanfaat bagi siapa saja yang membacanya.

Jadi intinya kenapa manusia harus berusaha dan berdoa jika takdir manusia berupa mati, rizki dan jodoh sudah ditetapkan dan tidak bisa diubah.

Berikut ini jawabannya.

Memang kematian, jodoh dan rezeki adalah takdir (ketetapan) yang telah ditentukan kepada manusia. Dalil tentang kematian sudah ditentukan adalah surah Ali Imron ayat 185 : “Dan setiap yang bernyawa tidak akan mati kecuali dengan izin Allah,sebagai ketetapan yang telah ditentukan waktunya”. Sedang tentang jodoh yang telah ditentukan adalah surah Ar Rum ayat 21 : “Dan diantara tanda-tanda (kebesaran)Nya ialah Dia menciptakan pasangan-pasangan untukmu dari jenismu sendiri agar kamu cenderung dan merasa tenteram kepadanya, dan Dia menjadikan di antaramu rasa kasih dan sayang. Sungguh, pada yang demikian itu benar-benar terdapat tanda-tanda (kebesaran Allah) bagi kaum yang berpikir”. Adapun tentang telah ditentukannya rezeki kita adalah surah Saba ayat 24 : “Katakanlah (Muhammad), “Siapakah yang memberi rezeki kepadamu dari langit dan bumi?” Katakanlah, “Allah”.
Jika kematian, jodoh dan rezeki sudah ditentukan, lalu mengapa kita berdoa dan berusaha untuk mendapatkannya? Jawabnya adalah : Pertama, berusaha dan berdoa adalah ciri khas manusia yang membedakannya dengan makhluk lainnya. Berusaha dan berdoa adalah bukti bahwa manusia memiliki kebebasan memilih. Ini adalah penghargaan tertinggi Allah kepada manusia, ciptaan-Nya. Jadi ketika kita berusaha dan berdoa sebenarnya kita sedang mensyukuri nikmat Allah (yakni kebebasan). Sebaliknya, orang yang tidak mau berusaha dan berdoa berarti dia melecehkan dan tidak bersyukur terhadap nikmat Allah berupa kebebasan itu sendiri.
Kedua, kita harus berusaha dan berdoa agar lebih cepat lagi mendapatkan takdir kita, jika takdir itu baik dan sesuai keinginan kita. Jika takdir tersebut tidak sesuai dengan keinginan kita, maka dengan berusaha kita dapat merubah takdir tersebut menjadi takdir yang baik atau sesuai dengan keinginan kita. Rasulullah bersabda : “Tidak ada yang dapat merubah takdir kecuali doa”. Dalam peristiwa dimana Umar bin Khatab ra bertanya kepada seseorang yang tidak mengikatkan keledainya sebelum masuk masjid lalu dijawab oleh orang tersebut, “Buat apa diikat? Jika memang takdirnya keledai saya tidak akan hilang?. Lalu Umar ra menjawab : “Berusahalah dahulu (dengan cara mengikat keledai), baru Anda bertawakal (pasrah dengan takdir)”. Dalam peristiwa lain, ketika Umar ra mengungsi Madinah karena sedang ada wabah penyakit, lalu ditegur oleh seseorang: “Mengapa engkau mengungsi? Bukankah jika takdirmu tidak akan terkena penyakit, maka engkau tidak akan terkena penyakit? Lalu Umar ra menjawab: “Aku berpindah dari takdir yang satu (diam saja) kepada takdir yang lain (mengungsi untuk menghindari wabah penyakit)”.
Jadi berusaha dan berdoa adalah hal yang wajib dilakukan oleh seorang muslim, jika ia ingin mendapatkan takdir yang sesuai dengan keinginannya. Jika pun takdir yang menimpanya tidak sesuai dengan keinginannya padahal ia telah berusaha dan berdoa, maka disitulah letak ke-Maha Bijaksana-an Allah SWT. Sedang kita adalah makhluknya yang bodoh untuk mengambil hikmah dari sebuah peristiwa. “Boleh jadi kamu tidak menyenangi sesuatu, padahal itu baik bagimu, dan boleh jadi kamu menyukai sesuatu, padahal itu tidak baik bagimu. Allah mengetahui, sedang kamu tidak mengetahui” (QS. 2 : 216).

Jadi sederhananya : Takdir Allah SWT yang ditetapkan bagi semua makhluknya itu tidak satu.Banyak takdir yang telah disediakan oleh Allah SWT tinggal makhluknya saja memilih takdir yang mana, misal jika manusia mempunyai pisau ditangannya maka dia bisa memilih takdir yang ada seperti menusukkan pisau ketubuhnya sendiri atau menggunakannya untuk mengupas apel…:D. itu semua takdir Allah SWT ( Pendapat saya )