Iseng: Infix to Postfix Converter dan Postfix Evaluator dalam Bahasa Java

Tulisan ini adalah kelanjutan dari 2 post sebelumnya (post1, post2). Post ini akan membahas mengenai algoritma konversi ekspresi infiks (ekspresi matematika dengan bentuk a op b, di mana a dan b adalah operan dan op adalah operator) ke posfiks (ekspresi matematika dengan bentuk a b op). Saya memanfaatkan StringTokenizer bawaan Java untuk mengambil setiap operator dan operan pada ekspresi infiks sebagai masukan, serta koleksi objek stack generik yang dibuat dari 2 post sebelumnya.

Algoritma Konversi Ekspresi Infiks ke Posfiks
  1. Buatlah sebuah stack operator kosong
  2. Masukkan ekspresi infiks yang akan dikonversi
  3. Ambil setiap token pada ekspresi infiks, lalu periksa setiap token
    • Jika token adalah operan, maka tambahkanlah sebagai notasi posfiks
    • Jika token adalah tanda kurung buka, maka push tanda kurung buka ke stack operator
    • Jika token adalah tanda kurung tutup, maka pop terus stack operator sampai bertemu tanda kurung buka
    • Jika token adalah operator, periksalah stack operator
      • Jika stack kosong, maka push token ke dalam stack operator
      • Jika stack ada isinya, maka bandingkan presedensi puncak stack dengan token
        • Jika presedensi lebih besar maka pop stack operator dan tambahkanlah sebagai notasi posfiks


    • Push token ke stack operator

  4. Ulangi langkah 3 hingga token habis
  5. Pop terus stack operator sampai kosong dan tambahkan sebagai notasi posfiks

Algoritma Evaluasi Ekspresi Posfiks
  1. Buatlah sebuah stack operan kosong
  2. Ambil setiap token pada ekspresi posfiks, lalu periksa setiap token
    • Jika token adalah operan, maka push token ke dalam stack operan
    • Jika token adalah operator, maka pop stack operan lalu simpan sebagai operan kedua, dan pop lagi stack operan lalu simpan sebagai operan pertama.
    • Lakukan perhitungan terhadap kedua operan sesuai dengan operator token

  3. Push hasil perhitungan ke dalam stack operan
  4. Ulangi langkah 1 dan 2 hingga token habis
  5. Pop stack operan dan kembalikan sebagai hasil evaluasi

Sementara itu implementasinya dalam Bahasa Java adalah sebagai berikut,

/**
 * @author     Aprian Diaz Novandi (13505102)
 * @version    2.0
 * @since      13 September 2008
 * @see        MyStack
 * @throws     MyInfixToPostfixException
 * Implementasi kelas yang mengubah ekspresi masukan infix ke postfix dan melakukan evaluasi terhadap ekspresi postfix
 */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.Double;
import java.lang.Math;
import java.util.StringTokenizer;

import MyCollection.*;

public class MyInfixToPostfix {
    private MyStack stackOfOperator;
    private MyStack stackOfOperand;

    public MyInfixToPostfix() {
        stackOfOperator = new MyStack();
        stackOfOperand = new MyStack();
    }

    public boolean isOperator(String token) {
        return (token.equalsIgnoreCase("^") || token.equalsIgnoreCase("*") || token.equalsIgnoreCase("/")  ||
                token.equalsIgnoreCase("%") || token.equalsIgnoreCase("+") || token.equalsIgnoreCase("-"));
    }

    public boolean isOperand(String token) {
        //sudah menangani kasus bilangan negatif
        return (!isOperator(token) && ((Character.isDigit(token.charAt(0))) || (token.charAt(0) == '-')));
    }

    //mengembalikan prioritas operator saat evaluasi
    public int precedence(char opr) {
        int retval;
        switch (opr) {
            case '^':    {    retval = 3;    break;    }
            case '*':    {    retval = 2;    break;    }
            case '/':    {    retval = 2;    break;    }
            case '%':    {    retval = 2;    break;    }
            case '+':    {    retval = 1;    break;    }
            case '-':    {    retval = 1;    break;    }
            default:    {    retval = 0;    break;    }
        }
        return retval;
    }

    public String convertToPostfix(String infixExp) throws Exception, MyInfixToPostfixException {
        StringTokenizer st = new StringTokenizer(infixExp);
        String curToken = "", postfixExp = "";
        int nKurungBuka = 0, nKurungTutup = 0;
        Character temp;

        while(st.hasMoreTokens()) {
            //mengambil token
            curToken = st.nextToken();
            if(isOperand(curToken)) {
                //jika currentToken adalah operand, maka kembalikan sebagai ekspresi postfix
                postfixExp = postfixExp + " " + (Double.parseDouble(curToken));
            } else if(curToken.equals("(")) {
                //jika currentToken adalah kurung buka, maka push tanda kurung buka ke stack operator
                Character opr = new Character('(');
                stackOfOperator.push(opr);
                nKurungBuka++;
            } else if(curToken.equals(")")) {
                //jika currentToken adalah kurung tutup, maka pop stack operator sampai ketemu kurung buka
                while(((Character)stackOfOperator.peek()).charValue() != '(') {
                    postfixExp = postfixExp + " " + stackOfOperator.pop();
                }
                temp = stackOfOperator.pop();
                nKurungTutup++;
            } else if(isOperator(curToken)) {
                //jika currentToken adalah operator
                if(stackOfOperator.isEmpty()) {
                    //stack operator masih kosong, maka push currentToken ke stack operator
                    Character opr = new Character(curToken.charAt(0));
                    stackOfOperator.push(opr);
                } else {
                    Character opr = new Character(curToken.charAt(0));
                    if (precedence(((Character)stackOfOperator.peek()).charValue()) > precedence(opr)) {
                        postfixExp = postfixExp + " " + stackOfOperator.pop();
                    }
                    //push currentToken
                    stackOfOperator.push(opr);
                }
            } else {
                //ekspresi tidak valid
                throw new MyInfixToPostfixException("Ekspresi tidak valid");
            }
        }

        //ekspresi tidak valid
        if(nKurungBuka != nKurungTutup)
            throw new MyInfixToPostfixException("Ekspresi tidak valid");

        //pop terus stack operator sampai kosong
        while (!stackOfOperator.isEmpty()) {
            postfixExp = postfixExp + " " + stackOfOperator.pop();
        }
        return postfixExp;
    }

    public double evaluate(String postfixExp) throws Exception {
        StringTokenizer st = new StringTokenizer(postfixExp);
        double retval;
        String curToken = "";

        while (st.hasMoreTokens()) {
            //mengambil token
            curToken = st.nextToken();
            if(isOperand(curToken)) {
                //jika currentToken adalah operand, maka push ke stack operand
                Double opn = new Double(Double.parseDouble(curToken));
                stackOfOperand.push(opn);
            } else {
                //jika currentToken adalah operator, maka evaluasi dua operan sebelumnya
                double opn2 = ((Double)stackOfOperand.pop()).doubleValue();
                double opn1 = ((Double)stackOfOperand.pop()).doubleValue();
                double result = 0;
                switch(curToken.charAt(0)) {
                    case '*':    {    result = opn1 * opn2;    break;    }
                    case '+':    {    result = opn1 + opn2;    break;    }
                    case '-':    {    result = opn1 - opn2;    break;    }
                    case '/':    {    result = opn1 / opn2;    break;    }
                    case '%':    {    result = opn1 % opn2;    break;    }
                    case '^':    {    result = Math.pow(opn1, opn2);    break;    }
                }
                Double opn = new Double(result);
                stackOfOperand.push(opn);
            }
        }
        retval = ((Double)stackOfOperand.pop()).doubleValue();
        return retval;
    }

    public static void main(String args[]) throws Exception {
        String infixExp = "", postfixExp = "";
        MyInfixToPostfix itp = new MyInfixToPostfix();

        System.out.println("PERHATIAN!");
        System.out.println("Pisahkah masing-masing operand dan operator (termasuk kurung buka dan tutup) dengan minimal satu buah spasi");
        System.out.println("--------------------------------------------------\n");
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Masukkan ekspresi infix: ");
            infixExp = br.readLine();
            postfixExp = itp.convertToPostfix(infixExp);

            System.out.println("Ekspresi postfix: " + postfixExp);
            System.out.println("Hasil evaluasi: " + itp.evaluate(postfixExp));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("--------------------------------------------------\n");
        }
    }
}

/**
 * @see    java.lang.Exception
 */
class MyInfixToPostfixException extends Exception {
    private String message;

    public MyInfixToPostfixException(String _message) {
        super(_message);
        message = _message;
    }

    public String getMessage() {
        return message;
    }

    public String toString() {
        return "MyInfixToPostfixException: " + getMessage();
    }

    public void printStackTrace() {
        System.out.println(this);
        super.fillInStackTrace();
    }
}

Di bawah ini adalah contoh pemanggilan programnya

Pemanggilan Program MyInfixToPostfix

Sampai di sini dulu tulisan saya tentang konversi ekspresi infiks ke posfiks dan juga evaluasi ekspresi posfiks. Semoga tulisan ini berguna bagi Anda :)

-KnightDNA-

Iseng: Linked-List Generik dan Stack Generik dengan Representasi Linked-List dalam Bahasa Java (bagian II)

Lanjutan dari post sebelumnya.

Sekarang adalah kelas Stack dan StackException (letakkan keduanya sebagai dua kelas public di dua file yang berbeda)
/**
 *    @author     Aprian Diaz Novandi (13505102)
 *    @version    1.0
 *    @since      13 September 2008
 *    @see        MyList
 *    @throws     MyStackException
 *    Implementasi kelas stack dengan representasi linked-list di Java
 */

package MyCollection;

public class MyStack extends MyList {
    //ukuran stack
    private int size;

    //puncak stack
    private ElmtList top;

    //ctor
    public MyStack() {
        super();
        top = first;
        size = 0;
    }

    public boolean isEmpty() {
        return top == null;
    }

    public int getSize() {
        return size;
    }

    public T peek() {
        return top.getInfo();
    }

    public void push(T item) {
        ElmtList node = new ElmtList(item);
        super.insertFirst(node);
        top = first;
        size++;
    }

    public T pop() throws MyStackException {
        T item = null;
        if(isEmpty()) {
            throw new MyStackException("Stack kosong");
        } else {
            ElmtList node = super.deleteFirst();
            item = node.getInfo();
            top = first;
            size--;
        }
        return item;
    }

    public String toString() {
        String retval = super.toString();
        return retval;
    }
}

package MyCollection;

public class MyStackException extends Exception {
    private String message;

    public MyStackException(String _message) {
        super(_message);
        message = _message;
    }

    public String getMessage() {
        return message;
    }

    public String toString() {
        return "MyStackException: " + getMessage();
    }

    public void printStackTrace() {
        System.out.println(this);
        super.fillInStackTrace();
    }
}

Selanjutnya kelas StackDriver untuk pengujian
import MyCollection.MyStack;
import MyCollection.MyStackException;

public class MyStackDriver {
    public static void main(String[] args) {
        MyStack S1 = new MyStack();
        MyStack S2 = new MyStack();
        try {
            S1.push(100);
            S1.push(101);
            S1.push(102);
            S2.push('(');
            int item = S1.pop();
            int itemTop = S1.peek();
            System.out.println("Item yang di-pop: " + item);
            System.out.println("Item di top of stack: " + itemTop);
        } catch (MyStackException e) {
            e.printStackTrace();
        } finally {
            System.out.println(S1);
            System.out.println(S2);
        }
    }
}
Oke, itu dulu keisengan saya di sela kebosanan mengerjakan TA untuk bagian pertama ini. Sampai jumpa di postingan saya selanjutnya tentang InfixToPostfix. Doakan TA saya lancar ya :D. Semoga berguna bagi Anda.

-KnightDNA-

Iseng: Linked-List Generik dan Stack Generik dengan Representasi Linked-List dalam Bahasa Java (bagian I)

Iseng-iseng ingin menambah daftar post, kali ini saya akan menyisipkan salah satu tugas mata kuliah S2 di Rekayasa Perangkat Lunak, IF-ITB. Mata kuliahnya Algoritma dan Pemrograman. Ya, sepintas namanya sama dengan mata kuliah yang pernah saya ambil saat tingkat satu kemarin, tapi ternyata setelah sang dosen (Pak Saiful) memberikan silabus kuliahnya tampaklah bahwa mata kuliah ini adalah lanjutan (lebih tepatnya ulangan dengan sudut pandang ala mahasiswa S2) dari trilogi pemrograman IF ITB (Algoritma dan Pemrograman, Algoritma dan Struktur Data, dan Pemrograman Beriorentasi Objek).

Materinya, karena masih awal-awal, banyak yang me-review kuliah S1 kemarin, termasuk tugas-tugasnya. Kebetulan tugas minggu ini adalah review OOP yang terkait dengan materi koleksi objek dan kelas generik. Judul post ini adalah tugasnya, dan sebenarnya akan dipakai untuk membuat kelas yang akan mengubah notasi operasi matematika infiks menjadi posfiks, lalu melakukan evaluasi terhadap notasi posfiks tadi dengan menggunakan stack. Tapi stack-nya harus dalam representasi linked-list.

Sebenarnya di Java sudah ada kelas-kelas koleksi objek tersebut (List, Stack, dan Queue/tidak dibahas di post ini) milik API Java, tapi pak dosen menyarankan mahasiswanya untuk mengkode sendiri koleksi objek yang diperlukan dalam tugas. So, here it is. Mudah-mudahan berguna bagi adik-adik tingkat saya yang nantinya akan mengambil kuliah Pemrograman Beriorientasi Objek atau siapa pun yang ingin mencoba-coba. Just correct me if I'm wrong!

/**
 *    @author     Aprian Diaz Novandi (13505102)
 *    @version    3.0
 *    @since      13 September 2008
 *    Implementasi kelas linked-list generic di Java
 */

package MyCollection;

import java.lang.NullPointerException;

public class MyList {
    static class ElmtList {
        //data
        private T info;
        //referensi ke elemen selanjutnya
        private ElmtList next;

        public ElmtList() {
            info = null;
        }

        public ElmtList(T _info) {
            info = _info;
        }

        public T getInfo() {
            return info;
        }

        public ElmtList getNext() throws NullPointerException {
            return next;
        }

        public void setNext(ElmtList node) throws NullPointerException {
            next = node;
        }

        public String toString() {
            if(next == null)
                return "[" + info + "|X]";
            else
                return "[" + info + "]->";
        }
    }

    //elemen pertama list
    protected ElmtList first;

    //ctor
    public MyList() { }

    public boolean isEmpty() {
        return first == null;
    }

    public ElmtList getFirst() {
        return first;
    }

    public void insertFirst(ElmtList node) {
        node.setNext(first);
        first = node;
    }

    public void insertLast(ElmtList node) {
        if(first == null)
            first = node;
        else {
            ElmtList P = first;
            while(P.getNext() != null) {
                P = P.getNext();
            }
            P.setNext(node);
        }
    }

    public ElmtList deleteFirst() {
        ElmtList node = first;
        if(node != null) {
            first = node.getNext();
            node.setNext(null);
        }
        return node;
    }

    public ElmtList deleteLast() {
        ElmtList P = first, Prev = null, retval = null;
        if (P == null) {
            //list kosong
            retval = null;
        } else if(P.getNext() == null) {
            //elemen list hanya satu
            first = null;
            retval = P;
        } else {
            while(P.getNext() != null) {
                Prev = P;
                P = P.getNext();
            }
            retval = P;
            Prev.setNext(null);
            P = Prev;
        }
        return retval;
    }

    public String toString() {
        ElmtList P = first;
        String retval = "";
        while(P.getNext() != null) {
            //cetak dan telusuri semua elemen
            retval += P.toString();
            P = P.getNext();
        }
        //cetak elemen terakhir
        retval += P.toString();
        return retval;
    }

    //driver, untuk pengujian
    public static void main(String[] args) {
        MyList L1 = new MyList();
        MyList L2 = new MyList();

        try {
            L1.insertFirst(new ElmtList(100));
            L1.insertFirst(new ElmtList(101));
            L1.insertFirst(new ElmtList(102));
            L1.deleteFirst();
            L2.insertFirst(new ElmtList("aku"));
            L2.insertFirst(new ElmtList("kamu"));
            L2.insertLast(new ElmtList("dia"));
            L2.insertLast(new ElmtList("mereka"));
            L2.deleteFirst();
            L2.deleteLast();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } finally {
            System.out.println(L1);
            System.out.println(L2);
        }
    }
}

Bersambung.

-KnightDNA-

PS: Saya mengelompokkan koleksi-koleksi objek tadi dalam satu package bernama MyCollection

Selayang Pandang Data Warehouse (bagian II)

Lanjutan dari artikel sebelumnya.

Arsitektur Data Warehouse
Secara umum, ada tiga macam arsitektur yang sering ada pada data warehouse, yaitu:

  1. Standar
    Pada arsitektur ini, data warehouse langsung mengambil data yang berasal dari berbagai data sumber tanpa adanya tahapan pengumpulan di tempat sementara sebelum masuk ke data warehouse.

    Arsitektur Data Warehouse Standar
  2. Dengan staging area
    Pada arsitektur ini, data warehouse membersihkan dulu data yang berasal dari berbagai data sumber ke suatu tempat penampungan antara (disebut dengan staging) sebelum masuk ke data warehouse. Proses pembersihan ini akan dijelaskan lebih rinci pada proses ETL (akan dibahas pada posting selanjutnya :P ).

    Arsitektur Data Warehouse dengan Staging
  3. Dengan staging area dan beberapa data mart
    Pada arsitektur ini, data warehouse akan dibagi lagi menjadi beberapa upabagian (subset) sesuai dengan tujuan maupun penggunanya (misal: subset penjualan perusahaan, subset pemasaran perusahaan, maupun subset inventaris perusahaan). Upabagian dari data warehouse ini biasa disebut sebagai data mart. Data mart itu sendiri tidak selalu dipadang sebagai sesuatu yang diturunkan dari data warehouse (pendekatan top-down), tapi data mart itu bisa dipandang sebagai komponen penyusun data warehouse (pendekatan bottom-up).

    Arsitektur Data Warehouse dengan Staging dan Data Mart

Catatan:

Hal, yang patut Anda perhatikan adalah bahwa staging itu bisa memiliki beberapa tingkatan (level), jadi data yang dijumlahkan (di-summarize) pada staging bisa memiliki level penjumlahan yang berbeda. Contohnya: staging data transaksi pada data warehouse suatu dealer motor bisa dijumlahkan per transaksi, per pelanggan, atau bisa jadi harian atau bulanan, tergantung dari kebutuhan user terhadap data warehouse.

Bersambung

-KnightDNA-

Selayang Pandang Data Warehouse (bagian I)

Akhirnya, sesuai dengan janji saya pada tulisan saya sebelumnya tentang data warehouse, kali ini saya akan kupas tentang data warehouse secara konseptual (belum terlalu mengarah ke teknik). Sebelumnya, saya mohon koreksi dari pembaca sekalian apabila Anda menemukan tulisan saya yang masih belum benar. Baiklah, saya mulai saja.

Definisi Data Warehouse

Salah satu efek yang dihasilkan dari adanya suatu sistem informasi adalah munculnya banyak data. Data yang ada ini berasal dari sistem operasional yang berfungsi untuk menangani transaksi yang terkait dengan proses bisnis yang ditangani oleh sistem informasi tersebut. Contoh: sistem informasi presensi karyawan memunculkan data jumlah kehadiran kehadiran karyawan setiap hari dengan data yang disimpan tergantung pada apa yang dibutuhkan oleh sistem informasi tersebut (misalkan: nomor induk pegawai, jam masuk, pintu masuk, dsb.). Bayangkanlah sistem informasi ini dipakai di perusahaan yang jumlah karyawannya sebanyak 1000 orang. Apabila data ini dipakai selama seminggu masa kerja saja (5 hari), maka data yang masuk dalam basis data ada 1000 x 5 = 5000 baris. Anda tinggal kalikan saja apabila ingin menghitung jumlah data yang disimpan selama seminggu waktu operasional, sebulan, hingga setahun. Itu baru satu sistem informasi saja. Di korporasi yang besar sistem informasi yang ada berjumlah banyak dengan berbagai fungsi dan tujuannya. Akhirnya masalah berikutnya muncul: dengan data yang banyak dan bermacam-macam ini, apa yang bisa saya peroleh/manfaatkan?

Solusi atas masalah tersebut adalah data warehouse! Lompati dulu makna dari frasa data warehouse ini. Untuk bisa tahu dan paham tentang data warehouse, Anda harus tahu dulu definisi dari OLTP. Dalam terminologi basis data, aplikasi yang ada pada sistem informasi untuk contoh kasus di atas menjalankan fungsi yang disebut dengan OLTP (Online Transaction Processing). Jangan terjebak kata online di sini yang tidak sama dengan online ke jaringan Internet. Kata online di sini artinya adalah tersambung langsung dengan basis data. Pada OLTP, hal yang paling penting adalah kecepatan pemrosesan transaksi, sehingga pada OLTP ini aplikasi akan terhubung dengan basis data yang mengalami normalisasi untuk performa pemrosesan transaksi yang lebih cepat dan juga bisa juga untuk efisiensi kapasitas media penyimpanan (data yang redundan jumlahnya berkurang).

Data Warehouse

Hal yang kontras dari OLTP (sistem operasional) akan ditemui pada Data Warehouse. Data Warehouse (yang secara harafiah berarti gudang data) adalah kumpulan seluruh data yang dimiliki oleh perusahaan yang didesain untuk melakukan analisis dan pelaporan, dan bukan untuk pemrosesan transaksi. Jadi, dalam istilah yang lebih sederhana, data warehouse adalah basis data yang ditujukan untuk analisis, pelaporan, dan terkadang juga untuk penambangan pengetahuan (knowledge mining). Data warehouse ini umumnya mengandung data historis yang diturunkan dari data yang dihasilkan oleh OLTP. Tidak menutup kemungkinan juga data warehouse ini juga mengambil data dari berbagai sumber data yang dimiliki oleh perusahaan yang tidak berasal dari basis data (misalkan: laporan keuangan biro tertentu yang berupa berkas/file spreadsheet). Karena sumber datanya bermacam-macam dengan skema dan format yang juga bermacam-macam, maka sebelum memasuki data warehouse, data harus mengalami proses ETL (extraction, transformation, dan loading) agar formatnya konsisten saat masuk ke data warehouse. Pembahasan rinci tentang ETL ini tidak dibahas di tulisan ini. Data warehouse merupakan bagian dari kecerdasan bisnis/business intelligence, yaitu penerapan teknologi informasi pada perusahaan yang berfungsi untuk membantu perusahaan dalam meningkatkan performa bisnis. Tujuan awalnya adalah untuk membantu perusahaan dalam proses penentuan keputusan (decision-making), sementara tujuan akhirnya tentu saja keuntungan perusahaan yang semakin berlipat :P .

Perbedaan OLTP dan Data Warehouse

Perbedaan mendasar antara OLTP dengan Data Warehouse terletak pada hal-hal di bawah ini:
  1. Query
    Query pada data warehouse kebanyakan berupa ad-hoc query, artinya query tersebut dibangkitkan secara dinamis lewat bentuk query yang terdefinisi di awal. Pola (kerangka) pada ad-hoc query sudah jelas, tapi saat melakukan analisis, bentuk (badan) query-nya bisa berbeda-beda. Hal yang berbeda akan ditemui di OLTP, yang memiliki query yang harus benar-benar terdefinisi di awal sesuai dengan kondisi (state) transaksi yang ditangani.
  2. Modifikasi Data
    Perubahan yang ada pada data warehouse bersifat tambahan saja dan umumnya bersifat borongan lewat proses ETL yang terjadwal secara periodik. Sementara pada OLTP, perubahan yang terjadi harus langsung dilakukan saat itu juga dan setiap modifikasi data yang ada harus konsisten dan benar (sesuai dengan setiap kondisi aktual dari proses bisnis yang ditangani).
  3. Desain Skema
    Data warehouse pada umumnya memiliki skema basis data yang didenormalisasi secara penuh atau didenormalisasi sebagian untuk memudahkan eksekusi analisis yang umumnya diimplementasikan dalam bentuk query agregasi dan kalkulasi rumit terhadap data multidimensi. Sementara pada OLTP, skema basis data mengalami normalisasi untuk memudahkan eksekusi transaksi yang terkait dengan operasi-operasi basis data (insert, update, delete), dan untuk menjamin konsistensi basis data.
  4. Operasi Umum
    Operasi umum yang implementasinya adalah berupa query analitik untuk data warehouse adalah operasi semacam ini, "Hitungnya masing-masing total penjualan produk X secara nasional per bulan sepanjang tahun 2007" atau "", sementara pada OLTP adalah, "Masukkan data pembelian produk ini (ke dalam basis data operasional)".
  5. Data historis
    Pada data warehouse ada banyak data historis dalam jangka waktu yang lama (umumnya dipakai untuk proses analisis). Sementara pada OLTP data yang disimpan jangka waktunya tidak lama, kalaupun ada data historis hanya diperlukan untuk proses transaksi pada saat itu.

Karakteristik Data Warehouse

Beberapa karakteristik dari data warehouse adalah:
  1. Subject oriented
    Karena data warehouse didesain untuk melakukan analisis maka data warehouse harus memproses query yang berupa pertanyaan yang bersifat subjektif, seperti "Produk apa yang paling laku dijual sepanjang tahun 2007?". Kemampuan untuk memecahkan masalah yang bersifat subjektif ini membuat data warehouse bersifat subject-oriented.
  2. Integrated Sumber data dari data warehouse adalah berbagai data yang dimiliki oleh suatu organisasi dari berbagai sumber dengan skema dan format yang bermacam-macam. Karakteristik ini terkait dengan fungsi data warehouse terhadap sumber data yang akan dimasukkan ke dalam data warehouse.
  3. Nonvolatile
    Data yang sudah masuk ke dalam data warehouse tidak bisa diubah lagi. Hal ini memang sesuai dengan salah satu tujuan dari data warehouse, yaitu analisis.
  4. Time-variant
    Data yang ada di dalam data warehouse akan dianalisis perubahannya berdasarkan waktu.

Bersambung

-KnightDNA-

Instalasi dan Konfigurasi Oracle BI Publisher pada Apache Tomcat

Halo semuanya,

Kali ini saya akan menulis petunjuk instalasi dan konfigurasi Oracle BI Publisher Enterprise Edition. Berikut ini lingkungan (environment) tempat saya melakukan instalasi. Mohon Anda perhatikan dulu,

LINGKUNGAN INSTALASI
  • Sistem operasi: Micro$*ft Wi*dows XP SP3
  • Spesifikasi hardware: Intel Core2Duo T8100 @2.10GHz, RAM 2,00GB
  • Server: Apache Tomcat 6.0.13
  • Versi JDK: 1.6.0 Update 6
  • Versi Oracle BI Publisher: 10.1.3.3.2

Berikut adalah langkah-langkahnya,

DEPLOYMENT ORACLE BI PUBLISHER SERVER
  1. Periksa folder installer BI publisher
    Pastikan terdapat 4 folder utama: doc/, install/, manual/, stage/, dan Translations/
  2. Silakan masuk ke Tomcat Web Application Manager
  3. Pilih bagian deploy (WAR file to deploy)
  4. Sebarkan (deploy) file bernama xmlpserver.war yang berada di folder manual/generic
  5. Apabila proses deployment berhasil maka path /xmlpserver akan muncul di bagian Applications dari Tomcat Web Application Manager

KONFIGURASI REPOSITORI DAN FONT ORACLE BI PUBLISHER SERVER
Setelah aplikasi berhasil di-deploy, silakan ikuti langkah-langkah di bawah ini,
  1. Salin (copy) folder XMLP/ dari manual/ ke server; tempatnya terserah Anda, asalkan masih berada di folder Apache Tomcat :D
    Misal: <direktori_apache_tomcat>/webapps/xmlpserver (tempat deployment aplikasi .war tadi), atau di tempat lain
    Catatan: <direktori_apache_tomcat> tempat saya ada di D:\apps\Tomcat6\, silakan sesuaikan dengan tempat Anda melakukan instalasi Apache Tomcat.
  2. Silakan modifikasi file xmlp-server-config.xml yang berada di <direktori_apache_tomcat>/WEB-INF/
    Akan muncul skema XML sebagai berikut
    
    
    
    
    
    
    
  3. Gantilah atribut path pada tag file dengan path tempat Anda menyalin folder XMLP/ pada nomor 1
    Misal:
    
    
  4. Salin (copy) font yang ada pada folder manual/fonts ke direktori font yang dipakai oleh Java Runtime Environment di tempat Anda masing-masing.
    Misal ke: D:\java\jre1.6.0_06\lib\fonts
  5. Jalankan ulang (restart) server Anda
  6. Sekarang silakan jalankan BI Publisher Server dengan membuka http://<hostname>:<port>/xmlpserver
  7. Masuk log dengan akun "Administrator" dan sandi (password) "Administrator"
  8. Selanjutnya, silakan lakukan konfigurasi minimal pada server (baca bagian selanjutnya).
    Catatan: demi keamanan, silakan modifikasi akun superuser Administrator tersebut.

Setelah Oracle BI Publisher server berhasil di-install, langkah selanjutnya adalah melakukan konfigurasi minimal, yaitu konfigurasi Scheduler dan Data Source. Konfigurasi hal lain tergantung dari kebebasan dan kreativitas Anda. Silakan baca Dokumentasi Oracle BI Publisher di folder doc/ pada tempat installer Oracle BI Publisher untuk tahu lebih lengkap. Hal tersebut akan terlalu banyak apabila diulas dalam satu tulisan ini.

Konfigurasi Oracle BI Publisher Scheduler
  1. Silakan masuk ke bagian Admin > Scheduler Configuration
      Masukkan parameter yang diperlukan, antara lain:
    • Jenis DBMS (yang didukung untuk penjadwalan hanya Oracle/minimal 8i, IBM DB2/minimal versi 6, Micro$*ft SQL Server, MySQL, dan Sybase)
    • Koneksi (memanfaatkan fasilitas JDBC, pastikan Anda sudah memiliki kelas driver untuk masing-masing DBMS)
      Contoh: jdbc:oracle:thin@localhost:1521:orcl apabila menggunakan DBMS Oracle dengan instans (instance) orcl
    • Akun (username) dan sandi (password), pastikan akun ini memiliki kewenangan (privilege) yang cukup untuk melakukan penambahan skema serta transaksi INSERT, UPDATE, dan DELETE record.
    • Kelas driver basis data (misal: oracle.jdbc.driver.OracleDriver untuk DBMS Oracle)

  2. Untuk menguji apakah koneksi ke basis data berhasil, silakan uji dengan mengklik tombol "Test Connection"
  3. Apabila sudah berhasil, silakan tambah skema untuk scheduler tadi dengan mengklik tombol "Install Schema"

Konfigurasi Oracle BI Publisher Data Source
  1. Silakan masuk ke bagian Admin > Data Sources
    Catatan: Perhatikan bahwa ada pengaturan untuk koneksi JDBC, koneksi JNDI, dan File (XML). Umumnya yang dipakai adalah koneksi JDBC atau File.
  2. Untuk file, yang didukung adalah file XML, dan untuk menambahkannya silakan klik "Add Data Source".
  3. Masukkan parameter yang dibutuhkan.
    Catatan: Perhatikan bahwa parameter Full Path of Top-Level Directory harus diisi dengan absolut path ke folder di mana Anda akan menaruh kumpulan file .XML di dalamnya.
    Misal: D:\data\xml
  4. Untuk koneksi JDBC atau JNDI silakan lakukan langkah serupa dengan masukan file XML
    Catatan: Perhatikan bahwa untuk parameter yang diperlukan pada JDBC mirip dengan langkah konfigurasi Oracle BI Publisher Scheduler, yaitu: Koneksi JDBC, username dan password, serta kelas driver basis data. Jangan lupa untuk memastikan koneksi sudah berhasil dengan mengklik tombol "Test Connection" terlebih dulu. Setelah itu, silakan klik tombol "Apply".

CATATAN
Segala perubahan yang terkait dengan konfigurasi server akan bisa berjalan setelah Anda menjalankan ulang server.

INSTALASI ORACLE BI PUBLISHER DESKTOP
Setelah instalasi dan konfigurasi minimal Oracle BI Publisher Server dijalankan, maka Anda sudah bisa membangkitkan laporan dengan sumber data yang ada dari data source atau file XML tersendiri. Selain itu ada plug-in integrasi Micro$*ft Office dengan Oracle BI Publisher yang bisa Anda manfaatkan, yaitu Word Template Builder (untuk membuat template menggunakan MS Word) dan Excel Analyzer (untuk OLAP). Untuk memanfaatkannya, silakan install Oracle BI Publisher Desktop dan ExcelAnalyzer yang terdapat di folder instalasi, subfolder manual/XMLP/Tools.

Instalasi bersifat GUI-based sehingga akan memudahkan Anda untuk memasukkan parameter yang diperlukan pada saat instalasi. Silakan ikuti langkah-langkah langsung pada saat instalasi setelah mengklik masing-masing installer tadi.

CATATAN
  1. Cara menggunakan Word Template Builder akan menjadi pembahasan tersendiri dan tidak di tulisan ini :D
  2. Oracle BI Publisher Desktop dan ExcelAnalyzer memerlukan platform .NET 2.0 untuk berjalan. Pastikan Anda sudah meng-install .NET 2.0 sebelumnya.

Demikian catatan instalasi Oracle BI Publisher dari saya. Semoga bisa membantu Anda yang memerlukan panduan tersebut. Pesan saya, tetap gunakan aplikasi legal dan jangan terjebak pada fanatisme penggunaan teknologi atau kakas tertentu. Mohon koreksi bila Anda menemui kesalahan pada tulisan di atas, atau ada bagian yang kurang lengkap. Silakan isi bagian komentar apabila Anda ingin berdiskusi dengan saya. Terima kasih dan semoga hari Anda menyenangkan selalu! :)

-KnightDNA-

Say Hello to Oracle BI Publisher

Halo semuanya,

Di awal Juli ini saya akan menulis artikel tentang Oracle BI Publisher. Mohon maaf, janji saya pada post sebelumnya tentang data warehouse belum bisa saya penuhi sekarang karena tulisan tentang data warehouse sifatnya sangat konseptual dan rupanya cukup njelimet (rumit) dan malas juga untuk menyusun tulisan tentang data warehouse agar mudah dibaca dan dipahami oleh pembaca, :D . Baik, kali ini saya akan langsung membahas tentang salah satu bagian dari pembangunan data warehouse, yaitu reporting system, utamanya tentang kakas (tool) yang saya gunakan pada saat kerja praktek ini yaitu Oracle BI Publisher.

Sebaiknya, Anda mengetahui dulu keterkaitan antara data warehouse dan reporting system. Kalau Anda sudah tahu, silakan lewatkan (skip) paragraf ini untuk beralih ke paragraf berikutnya :D . Data warehouse (bagian yang lebih detail dan teknis ada di post yang lain :P ) dibuat dengan tujuan untuk melakukan analisis terhadap data historis yang dimiliki oleh suatu organisasi (umumnya korporat), dan analisis ini digunakan sebagai penunjang keputusan atau kebijakan yang akan diambil oleh perusahaan. Nah, hasil akhir dari analisis data historis tadi bisa berupa berbagai laporan yang ditujukan untuk kalangan eksekutif perusahaan (umunya top level management). Contoh: Laporan hasil penjualan produk XXX (jangan ngeres dulu ya... :D ) di seluruh Indonesia yang akan ditujukan untuk manajer pemasaran PT XYZ. Laporan ini nantinya bisa dilihat lebih detail per provinsi (misalnya), atau per kabupaten, sehingga sang manajer pemasaran bisa tahu tren pasar secara hierarkis (dari nasional ke aras/level di bawahnya) dari laporan tersebut. Dari situ akhirnya sang manajer bisa memutuskan langkah perusahaan ke depan terkait dengan strategi pemasaran produk tersebut. Got the point? ;)

Oracle BI Publisher


Salah satu kakas (tool) yang cukup andal dalam masalah enterprise reporting system ini adalah Oracle BI Publisher (dulu bernama XML Publisher, karena data mentah keluarannya berformat XML, bahkan hingga saat ini). Ada beberapa kelebihan tentang kakas ini, yaitu:

  1. Terintegrasi dengan Micro$*ft Word, jadi, pengguna enterprise reporting system bisa melakukan pembangunan template laporan menggunakan kakas dokumen produksi Micro$*ft yang mudah dipakai dan mahal ini. Yang perlu Anda catat, Word Template Builder ini perlu platform .NET 2.0 agar bisa digunakan.

  2. Mampu mendukung pengiriman lebih dari satu channel (web, FTP, e-mail, faks, printer).

  3. Mampu mendukung format keluaran yang bermacam-macam (XML/mentah, HTML, MHTML, PDF, CSV, PPT).

  4. Menyediakan fasilitas penjadwalan untuk pengiriman laporan (sepertinya ini merupakan standar dari suatu enterprise reporting system).

  5. Menyediakan layanan web service, sehingga fasilitas pembangkitan laporan bisa dipanggil melalui aplikasi lain.

  6. Mampu mendukung template animasi Flash, jadi laporan yang dibuat bisa menjadi laporan yang menarik dan interaktif.

  7. Mampu mendukung berbagai sistem manajemen basis data (RDBMS); tidak terbatas keluarga Oracle saja. Anda juga bisa mengambil data yang berada pada RDBMS MySQL, dan RDBMS lain asalkan didukung oleh Java Database Connectivity (JDBC) :D . Satu lagi, Anda bisa langsung menjadikan file XML sebagai sumber data, asalkan skemanya sesuai. Pembahasan tentang skema XML ini masuk ke bagian teknis, dan tidak akan dibahas di sini.


Baru 7 hal tersebut kelebihan Oracle BI Publisher yang saya ketahui sejauh ini. Saya belum pernah membandingkan aplikasi enterprise reporting system yang lain, jadi pendapat di atas masih kurang objektif. Harap maklum saja, sebelumnya saya hanya mendapatkan teori dan konsep saja pada saat kuliah :D .

Sementara itu, beberapa hal yang menurut saya "kurang" dari kakas ini adalah tentu saja dari segi harga :( . Yup, Oracle BI Publisher memang termasuk golongan aplikasi proprietary yang biasa dipakai kalangan korporat. Tapi tentu saja kocek dan kemampuan menurut saya sudah cukup sebanding. Hehe, beruntung juga saya bisa mencoba satu contoh kakas mahal secara legal.

Apabila Anda tertarik untuk melihat aplikasi Oracle BI Publisher, silakan kunjungi halaman resminya, dan apabila Anda ingin tahu lebih banyak tentang cara penggunaannya, silakan kunjungi blog Oracle BI Publisher.

Sampai di sini dulu tulisan pengantar dari saya tentang Oracle BI Publisher. Sampai jumpa di tulisan selanjutnya tentang langkah instalasi dan konfigurasi Oracle BI Publisher. Saya berencana untuk mempublikasikan banyak artikel seputar kerja saya di sini, termasuk tentang Oracle BI Publisher :D . Terakhir, mohon koreksi apabila Anda menemui kesalahan.

-KnightDNA-

Membuat CAPTCHA Sederhana

CAPTCHA (kepanjangan: Completely Automated Public Turing test to tell Computers and Humans Apart) adalah gambar yang mengandung kode alfabetik, numerik, ataupun alfanumerik, yang pada umumnya mudah dibaca oleh manusia namun susah (bahkan tidak bisa) dibaca oleh komputer. CAPTCHA bisa dibuat dengan menggunakan skrip PHP dan ekstensi GD yang berfungsi untuk membangkitkan grafik. Tulisan ini akan mengulas tentang cara membuat CAPTCHA sederhana. Anda cukup menyediakan web server Apache dengan modul PHP 5 dan ekstensi GD versi 2.0.34.

Berikut ini adalah langkah-langkah untuk membuat CAPTCHA:
  1. Buatlah session untuk menyimpan hasil pengacakan string.
  2. Definisikan gambar yang akan dibuat (tentukan ukuran, dan warna yang akan memenuhi gambar tersebut).
  3. Persiapkan string yang akan diacak.
  4. Tambahkan komponen-komponen yang akan memperkuat pengamanan CAPTCHA: font yang unik, penambahan background, penambahan garis-garis, rotasi teks, pembuatan font dengan ukuran masing-masing karakter yang berbeda, dsb.
  5. Bangkitkan CAPTCHA dengan menghidupkan session, dan memanggil fungsi pembangkit gambar yang ada pada ekstensi GD.

Contoh source code-nya ada adalah sebagai berikut (Anda boleh mengutip, mengedit, memodifikasi, dan menyebarkannya),

/**
 * @name  image.php
 * @author  Aprian Diaz Novandi
 * @todo  Skrip PHP yang menghasilkan gambar berformat .PNG dari string hasil pengacakan huruf kapital dengan font jenis AnkeCalligraph.TTF
 * @version 1.0.0.0
 * @since  May 15th 2007
 */

//memulai session untuk menyimpan hasil pengacakan string
session_start();

//membuat gambar berukuran 150x50 piksel
$im = imagecreatetruecolor(150, 50);

//definisi warna
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 175, 175, 175);
$black = imagecolorallocate($im, 0, 0, 0);

//membuat kotak berwarna putih dari titik (0,0) s.d. (150,50)
imagefilledrectangle($im, 0, 0, 150, 50, $white);

//string teks yang akan diacak
$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

//mengambil enam karakter saja dari hasil pengacakan string
$text = substr(str_shuffle($str),0,6);

//font yang dipilih
$font = 'Walrod-Regular.TTF';

/*parameter fungsi imagettftext
(gambar_sumber,ukuran_font,sudut,x,y,warna,jenis_font,text_yang_akan_ditulis)*/

//menambahkan bayangan
imagettftext($im, 22, 0, 10, 35, $grey, $font, $text);

//menambahkan teks
imagettftext($im, 16, 0, 10, 35, $black, $font, $text);

//menghidupkan session
/*nilai variabelnya bisa dienkripsi, bisa plain, 
agar lebih aman silakan dienkripsi*/
$_SESSION['randstr'] = sha1($text);

header("Content-type: image/png");
imagepng($im);
imagedestroy($im);

Kode di halaman tersebut adalah kode untuk gambar CAPTCHA-nya. Simpanlah di file yang berbeda (misalkan bernama image.php). Untuk menampilkan gambar tersebut, silakan gunakan tag image pada HTML.



Dan untuk mencocokkan gambar yang muncul, silakan bandingkan kesamaan input dari form dengan variabel $_SESSION['randstr']. Apabila pada kode gambar CAPTCHA, nilai variabel $_SESSION['randstr'] dienkripsi (misal menggunakan algoritma enkripsi SHA1), tentu input tersebut juga harus dienkripsi.

Skrip di atas masih memiliki kelemahan, yaitu masih bisa diinterpretasi oleh aplikasi yang memanfaatkan aspek kecerdasan buatan (computer vision). CAPTCHA yang baik adalah CAPTCHA yang susah diinterpretasi oleh aplikasi semacam itu. Saat ini, semakin banyak aplikasi yang dikembangkan untuk mematahkan pengamanan halaman web dengan CAPTCHA, dan biasanya akan dipakai oleh mesin penyebar spam.

Untuk melihat contoh aplikasi yang memanfaatkan CAPTCHA, Anda bisa menuju link: http://arc.itb.ac.id/~diaz/captcha

Tips di bawah ini barangkali berguna untuk Anda yang tertarik untuk bermain-main dengan CAPTCHA:
  1. Hindari pembuatan CAPTCHA tanpa latar belakang karena akan semakin memudahkan aplikasi pembaca kode CAPTCHA. Paling tidak buatlah tambahan garis-garis atau buatlah dengan pilihan font yang unik tapi masih terbaca manusia
  2. Modifikasilah karakter-karakter CAPTCHA yang dibuat dengan merotasi karakter dan/atau mengatur ukuran karakter tersebut agar berbeda.

-KnightDNA-

Enabling Syntax Highlighting in Wordpress

Hi all,

Tonight, while doing my business as an Informatics ITB university students in sixth term :P, I suddenly found an interesting plug-in of Wordpress that maybe has been already known by some of Wordpress user, but I do not think that all of Wordpress users know about this. It is SyntaxHighlighter plug-in. It will make you easier to post source code in Wordpress, so perhaps most of Informatics university students will activate this plugin on their own blog.

Well, I guess that you will just activate the plug-in and it will automatically work if you are a native Wordpress user - which means your blog are hosted on wordpress.com -, but how about a non-native Wordpress user like me (for your information, I am currently using Wordpress 2.3.3), whose blog is hosted in my own machine? So, here are the following action to activate the SyntaxHighlighter plug-in:
  1. Download the SyntaxHighlighter plug-in from wordpress official plug-in site. Just download the syntaxhighlighter.zip.
  2. Do not forget to download the core scripts (some JavaScript scripts) on Google Code, because Wordpress uses the SyntaxHighlighter JavaScript package by Alex Gorbatchev - I would like to say thank you very much to this person -. Download the SyntaxHighlighter_1.5.1.rar.
  3. Extract the first one of those compressed files in your Wordpress plug-in directory (wp-content/plugins/). The new folder will be created and its name is syntaxhighlighter.
  4. Go to syntaxhighlighter directory.
  5. Create a new directory namely files.
  6. Extract the last one in any place of your machine (it is not obligatory to extract it into your Wordpress plug-in directory). It will contain three directories: Scripts, Styles, and Uncompressed.
  7. Copy all files contained in Scripts and Styles directory into files directory (which mentioned in step 5) inside of your syntaxhighlighter directory. If your server operating system is UNIX family, please make sure that you have set the permission of your plug-in directory correctly.
  8. Now, you may enable the SyntaxHighlighter plug-in via Wordpress administration page. Just go directly to Plugin, and then activate your SyntaxHighlighter plug-in.

If it works, you can post your source code like this following example:

#include "Parser.h"

List parseLine(char* line) {
    List L;

    for(int i = 0; i < len(line); i++) {
        if(isNumber(line[i])) {
            //kalau bertemu angka
            char* temp = (char *)malloc(255*sizeof(char));
            for (int j = 0; j < 255; j++) {
                temp[j] = '';
            }

            j = 0;
            while(line[i] != ',') {
                temp[j] = line[i];
                i++;
                j++;
            }

            Point P;
            P.setX(atoi(temp));

            i++;
            j = 0;
            while(line[i] != ']') {
                temp[j] = line[i];
                i++;
                j++;
            }
            P.setY(atoi(temp));
            L.addLast(P);
        }
    }
    return L;
}
Just simply write your code inside of [sourcecode language='supported_language'] ...[/sourcecode], but do not forget to assign the language attribute of the sourcecode tag. There are several programming languages that have been supported by this plug-in (e.g.: C++, C#, Java, JavaScript, XML, etc.). It is better if you see its official FAQ. Do not forget to check your Wordpress version first, because it requires version 2.3.0 or above. This is all of my post for today. Actually, this is not the only way to enable the SyntaxHighlighter plug-in. Perhaps, you have the other way to enable it with the simpler steps. Alas! I still have to do my other tasks. They are Computer Graphics task and also other non-academics tasks that need to be done! So, good night everybody, I have got to go, but do not forget to leave your comment here if you are interested with the topic. :D

-KnightDNA-

Typological Error in Squirrelmail 1.4.0

If you install Squirrelmail as your webmail application, have you ever seen this following error messages?
Warning: preg_split() expects parameter 4 to be long, string given in /usr/local/www/squirrelmail/functions/imap_messages.php on line 806

Warning: Invalid argument supplied for foreach() in /usr/local/www/squirrelmail/functions/mime.php on line 53

I found this little bit irritating bug when I was replying an e-mail from my friend. For your information, I had installed Squirrelmail version 1.4.0 in my own server. Actually it wasn't only the core Squirrelmail application, but also the additional UI theme.

Actually, there was no functionality impact on writing/sending e-mail. The mail can still be sent and delivered successfully, but those error messages are just a bit annoying to me. So, I searched the bug fix via Google, and then I found the solution easily. Voila! Just a typological error, and here is the solution,

Open the file which is first mentioned in the error message, and go to the following line (806).
Replace this line:

$flags = preg_split('/ /', $regs[1],-1,'PREG_SPLIT_NI_EMPTY');

with

$flags = preg_split('/ /', $regs[1],-1,PREG_SPLIT_NO_EMPTY);

That's all. Thanks for viewing and have a good day!

-KnightDNA-

Some Tips on VIm and UNIX Shell

VIm (VI Improved)

VIm (VI Improved) is probably one of the most powerful text editors in UNIX. Its latest version is 7.1, and you can download it on its official web site. One of the powerful features is syntax highlighting, which can make VIm users be able to recognize some keywords of programming or scripting language by just seeing the different color on each keyword. Now, VIm has supported many popular programming and scripting language.

In my server, which is using FreeBSD 6.3 as the operating system, I have installed VIm-7.1 via port. Just do this following action:
  1. Go to port installation directory of VIm
    #cd /usr/ports/editors/vim
    
  2. Execute the port installation
    #make config install clean
    
  3. Wait until port installation is finished. It is not too long. Probably it will just take about 1 minute.
  4. After you have finished your installation, create a file .vimrc in your home directory For example, my username is knightdna and my home directory is in /home/knightdna, so I create .vimrc in that directory and write these on my .vimrc:
    syntax on
    set tabstop=4
    set showmatch
    
    The first line is used to enable the syntax highlighting feature of VIm, the second one is to set the count of the space in a tab key while using the editor, and the last is to show the command in VIm that probably match by just pressing the tab key. (e.g.: while writing :set n in command mode, if you press the tab key, VIm will automatically recognize your writing as :set number command).
  5. Then rehash your shell by do this following command:
    #rehash
    

Now you can use your fresh installed VIm with its one of powerful features, syntax highlighting.

UNIX Shell Configuration

There are few types of shell in UNIX (e.g.: bash, csh, and tcsh). I prefer using csh compared to the others since it has more support on programming and scripting (correct me if I'm wrong).

There is a file in your home directory which specifies the configuration of your shell. If you are using csh, then the file is .cshrc. If you are using bash, then the file is .shrc. We need to modify .cshrc file to enable color mode while using ls command, and the shell will also print your working directory.
  1. Go to your own home directory (e.g.: /home/knightdna)
    #cd /home/knightdna
    
  2. Open your .cshrc file with VIm (you may use the other editor)
    #vim .cshrc
    
  3. Add the alias of ls command with ls -FG. Write it on the line where the command aliases is declared. This is to enable color mode while you are using ls command
    alias ls ls -FG
    
  4. Change the value of your set prompt parameter. This is to print your current working directory while using your shell.
    set prompt = '\n[%B%m%b]%B%~%b%# '
    
  5. Save your .cshrc file and then quit from your VIm editor :wq
  6. Rehash your shell
    #rehash
    

Now you can use the ls command with color mode, and you'll notice the difference on your shell, right? That's all my simple tip for VIm and UNIX Shell Configuration. Hope this information is useful for you to make you more comfortable and enjoy your work with UNIX environment, especially when you are working in command line interface mode. Just correct me if I'm wrong. Thanks for viewing and have a good day!

-KnightDNA-

Activating the Wordpress Permalink

Hi all,

I have created permalinks in my blog. Previously, I didn't know how to make it works because I guessed that it would work by just adding a .htaccess file in my blog directory. But it still didn't work! So, here is the way to solve that problem (for your information, I'm using Apache 2.2.8 as web server with PHP 5.2.5 module installed here):
  1. When you activate your permalinks, make sure that you've set your .htaccess file to be writable (changing permission in command line interface with chmod 766 .htaccess). If your Wordpress application have permission to write your .htaccess file, its content will be:
    # BEGIN WordPress
    
    RewriteEngine OnRewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    
    # END WordPress
    

  2. Make sure that you have defined rewrite module in your Apache web server configuration (httpd.conf):
    
    RewriteEngine On
    RewriteRule   ^/~([^/]+)/?(.*) /u/$1/$2  [R]
    RewriteRule   ^/([uge])/([^/]+)$ /$1/$2/  [R]
    
    

  3. Do not forget to change the value of AllowOverride parameter in <Directory "[root_directory]" /> tag from None to All and also your Options parameter from None to Indexes FollowSymLinks as it will pay attention to your .htaccess file. Here is actually the key, because if you do not change this value, your .htaccess file will be useless. [root_directory] is the directory where you put your Wordpress source. So, the content of <Directory "[root_directory]" /> tag in your web server configuration file will be:
    
    Options -Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
    
    

  4. Restart your Apache web server via command line interface
    #apachectl restart
    

  5. You could try to test your permalink now

If your permalink activation is successful, you do not have to access your blog post like this following URL http://blog.knightdna.com/?page_id=k2, but instead you could access your blog based on post date or category (it depends on your setting in permalink activation), for instance http://blog.knightdna.com/2008/02/27. In case you do not know how to activate your permalink, just go to your administration page. Select Options then select Permalinks. Afterwards, you may customize your permalink structure.

That's all about activating the Wordpress permalink, especially if your blog is not hosted on wordpress.com. Hope this trick could be useful for you. Thanks and happy surfing! :D

-KnightDNA-