Jumat, 28 Oktober 2016

Implementasi Red-Black Tree Dalam C – Part 2

Jika belum baca part 1, silahkan baca dulu sebelum membaca yang ini. OK ?
Pada tulisan ini, pembahasannya akan ditujukan pada pemahaman awal sebelum insertion. Juga, tulisan ini akan sedikit menyinggung tentang sedikit prinsip kerja binary tree. Jadi, bagi yang belum tahu apa-apa, bisa memperoleh sedikit gambaran, kan.

Red-black tree memiliki prinsip dasar seperti binary tree biasa. Dalam binary tree setiap node punya field pointer ke parent, pointer ke left child node, dan pointer ke right child node. Setiap right node pasti memiliki nilai yang lebih besar; dan left node memiliki nilai yang lebih kecil.
Misalnya, kita masukkan nilai 10, 13, 4, 11 dan 15..


Tidak ada yang aneh ?
Hmm, bagaimana jika ditambah beberapa nilai lagi ? +16, 17, 18 dan 19 ?

WTF. Panjang sekali! Jangan kawatir, hal ini tidak akan pernah terjadi pada red-black tree. Saat terjadi violation, red-black tree akan melakukan sejumlah operasi untuk menyeimbangkan tree. Operasi yang saya maksud adalah operasi rotasi lalu diikuti dengan merubah warna node. Hal ini terus dilakukan hingga tidak ada node yang mengalami violation.

Sebelum tahu benar-benar bagaimana proses insertion dilakukan, pertama kita ketahui bagaimana cara merotasi node.

Node bisa dirotasi ke arah kiri, ataupun ke kanan; tergantung kondisi violation. Proses rotasi bisa dilihat di gambar berikut. Jika merasa bingung, coba gambarkan dalam secarik kertas dan imajinasikan bagaimana node bergerak dan berganti kaki dalam pikiran anda.


Biar lebih mudah, berikut pseudo-code nya.

LEFT-ROTATE(T, x)
    y ← x->right
    x->right ← y->left
    y->left->parent ← x
    y->parent ← x->parent
    IF x->parent = null THEN
        T->root ← y
    ELSE
        IF x = x->parent->left THEN
            x->parent->left ← y
        ELSE
            x->parent->right ← y
    y->left ← x
    x->parent ← y

RIGHT-ROTATE(T, x)
    y ← x->left
    x->left ← y->right
    y->right->parent ← x
    y->parent ← x->parent
    IF x->parent = null THEN
        T->root ← y
    ELSE
        IF x = x->parent->right THEN
            x->parent->right ← y
        ELSE
            x->parent->left ← y
    y->right ← x
    x->parent ← y


Dan, jika anda sudah paham bagaimana melakukan rotasi, coba pahami kode hasil implementasi yang sudah saya buat berikut. Jika sulit, pandangi kembali proses rotasi serta pseudo-code nya.

void rotate_left(RBTree *tree, RBTreeNode *x){
 RBTreeNode *y = x->right;
 x->right = y->left;
 
 if(y->left) y->left->parent = x;
  y->parent = x->parent;
 if(x->parent == 0)
  tree->root = y;
 else if(x == x->parent->left)
   x->parent->left = y;
  else
   x->parent->right = y;
 x->parent = y;
 y->left = x;
}

void rotate_right(RBTree *tree, RBTreeNode *x){
 RBTreeNode *y = x->left;
 x->left = y->right;
 
 if(y->right) y->right->parent = x;
  y->parent = x->parent;
 if(x->parent == 0)
  tree->root = y;
 else if(x == x->parent->left)
   x->parent->left = y;
  else
   x->parent->right = y;
 x->parent = y;
 y->right = x;
}
 
Aduh, rumit sekali, ya. Padahal masih part 2!
Hahaha, Don't worry, saya masih punya banyak part untuk dijejalkan pada anda. Tapi, untuk insertion, kita cuma butuh 1 part lagi. Just wait it..
Sembari menunggu part selanjutnya, anda bisa mendalami proses rotasi, sembari meminum secangkir kopi. :D
Read more

Implementasi Red-Black Tree Dalam C – Part 1



Baru pertama belajar data structures, langsung berhadapan dengan yang namanya red-black tree. Linux adalah alasan saya mempelajari struktur data yang satu ini. Dalam sistem internal linux, red-black tree banyak digunakan untuk menyimpan data sistemnya, misalnya data free page memory.

Saat ini saya sedang mengembangkan sistem operasi dari scratch di Programmer OS Indonesia. dengan bercermin pada Windows dan Linux, sayapun membuat inovasi yang menggabungkan kelebihan antara keduanya. Memory management adalah sektor yang sedang saya fokuskan kali ini.

Saya lihat, banyak source code linux mengimplementasikan red-black tree. Saat pertama mendengar istilah ini, saya tidak tahu apa-apa. Akhirnya, dengan berbekal google, saya mendalami red-black tree ini. Bukan Cuma teori tapi praktek juga. So, langsung saja kita bahas red-black tree nya.

Red-black tree adalah salah satu bentuk struktur data BST(Binary Search Tree) yang menerapkan balancing dalam kerjanya. Untuk melakukannya, sebuah node red-black tree disertai dengan atribut yang menyatakan properti bernilai merah atau hitam. Secara umum, bentuknya sama dengan struktur binary tree pada umumnya; ada parent, left child dan right child. Karena ini red-black tree, ada 1 lagi, field colour yang menunjukkan field ini merah atau hitam.


typedef struct _RBTreeNode {
    int data;
    int colour; //0 for black
    struct _RBTreeNode *parent;
    struct _RBTreeNode *left;
    struct _RBTreeNode *right;
} RBTreeNode;

typedef struct RBTree {
    RBTreeNode *root;
} RBTree;

Menurut referensi, algoritma red-black tree tidak jauh berbeda dengan AVL tree. Red-black tree tidak banyak melakukan balancing seperti AVL tree, jadi proses insertion lebih cepat. Sebagai imbasnya, tentu pencarian data dalam red-black tree lebih lambat jika dikomparasi dengan AVL tree. Akan tetapi, dengan kesederhanaan proses balancing yang dilakukan, red-black tree cenderung lebih cepat melakukan insertion dan deletion. Itu juga mengapa red-black tree digunakan dlam memory management di linux, karena dalam pekerjaan ini banyak dilakukan insertion dan deletion.
Cara kerja red-black tree ditentukan oleh field colour yang terdapat pada setiap node. Setiap node tidak boleh melanggar aturan pewarnaan berikut.

1. Setiap node memiliki warna merah atau hitam.
2. Root node (node paling awal) SELALU hitam.
3. Setiap leaf(daun) adalah hitam. Leaf adalah istilah untuk node NULL. Maksudnya? Misalnya node tidak memiliki left child dan right child. Artinya field node->left dan node->right nya kan 0, tuh. Nah node NULL itulah yang dimaksud leaf.
4. Jika node berwarna merah, kedua child node (left child & right child) HARUS hitam.
5. Untuk setiap node, yang setingkat harus memiliki jumlah node hitam yang sama jika diturut dari node tersebut hingga ke leaf. Ingat, leaf adalah hitam.


Prinsip kerjanya, nanti ketika dilakukan insertion, node baru akan diberi warna awal merah. Jika terjadi violation (melanggar catatan-catatan di atas), maka proses balancing akan dilakukan. Misalnya, ketika parent berwarna merah; nah, kan jika node merah, kedua child-nya harus hitam..

OK, sampai itu dulu pembahasan awal red black tree. Yang ini buat pengantar saja. Kalau banyak-banyak entar takut pusing. Untuk implementasinya, tunggu part 2 ya..
Read more

Selasa, 25 Oktober 2016

Membuat Desain Web Responsive Part 2 (Tips)


Di tulisan sebelumnya, kita sudah melihat bagaimana gambaran kasar sebuah desain responsif. Selanjutnya, pada tulisan ini akan serius membahas mengenai kompatibilitas web browser terhadap website yang telah dibuat.

Dengan membuat desain responsif, artinya kita ingin website ini dapat diakses dengan normal di browser manamun. Akan tetapi, kadang kala ada banyak hal di luar keinginan terjadi. Kasus ini mulai terjadi ketika diuji-cobakan pada perangkat browser mobile.

Jika tampilan web dapat berubah menyesuaikan diri ketika browser di-resize, itu masih belum cukup. Dukungan browser terhadap aspek-aspek website jangan sampai dilalaikan. Berikut adalah beberapa catatan yang dapat dijadikan sebagai acuan ketika mendesain web responsif.

1. Web browser mobile
Di antara beberapa jenis mobile web browser, sepertinya banyak pengguna menyukai browser dengan fitur proxy, seperti Opera mini dan UCBrowser. Hati-hati, beberapa aspek yang terlihat umum di web browser komputer seringkali tidak didukung dengan baik pada web browser mobile seperti ini. Beberapa contoh diantaranya adalah properti shadow, gradient-fill,border-radius. Properti ini ternyata tidak didukung pada Opera mini. Selain itu, list-style:none juga tidak bekerja ketika menggunakan web browser yang agak jadul.
Oleh karena itu semua, sebaiknya dekorasi dan estetika dibuat dengan tag HTML dan properti CSS umum yang banyak didukung oleh banyak web browser; tidak perlu muluk-muluk.

2. Javascript
Beberapa web browser mobile tidak mendukung javascript sepenuhnya. Opera mini sebagai salah satu web browser mobile yang banyak dipakai, perlu dipelajari. Yang harus diketahui adalah Opera mini menjalankan javascript melalui server-side, terkadang javascript tidak dapat berjalan dengan baik. Untuk itu, penggunaan javascript sebaiknya dikurangi, dan dicarikan alternatif lain.

3. Penting untuk memisahkan 2 elemen yang berdampingan saat berada dalam tampilan mobile
Ukuran lebar screen browser mobile terbatas, jadi ketika web menghadapi tampilan sepeti ini, ia harus dapat memecah element berdampingan yang kita buat float pada tutorial sebelumnya. Caranya adalah dengan rule @media pada CSS.

    @media screen and (max-width: 500px) {
        .content-left{
            width:100%;
        }
        .content-right{
            width:100%;
        }
    }
    @media screen and (min-width: 501px) {
        .content-left{
            width:50%;
        }
        .content-right{
            width:50%;
        }
    }
    .content-left{
        height:200px;
        background:#DDD;
        float:left;
        box-sizing:border-box;
    }
    .content-right{
        height:200px;
        background:#AAA;
        float:left;
        box-sizing:border-box;
    }


4. Atur juga susunan konten
Jika website anda memiliki 3 kolom konten atau bahkan lebih, jangan terlalu banyak memberikan konten di bagian sebelah kiri. Apalagi jika diisi banyak iklan. Ketika elemen berdampingan harus dipisah, halaman yang tampil paling atas adalah dari kolom paling kiri. Jangan sampai pengunjung awam mengira bahwa ia sedang salah klik, karena melihat konten kurang relevan di bagian paling atas.

5. Sebaiknya jangan gunakan menu popup dan jangan daftar iklan popup (opsional)
Ini terkait dengan dukungan browser terhadap javascript. Navigasi menu terkadang kurang optimal dan tidak bekerja dengan baik di tampilan mobile. Sama pula pula iklan popup yang pada umumnya menggunakan javascript. Jangan sampai pengunjung kabur karena iklan-iklan ini.

6. Gunakan gambar seperlunya (opsional)
Tidak semua perangkat mobile memiliki spesifikasi yang cukup untuk mengakses website kita jika kita banyak memasang gambar.

7. Gunakan tipografi font internal daripada webfont
Benar, webfont lebih lengkap dan lebih indah kenampakannya, tapi tidak semua browser mobile mendukung penyertaan webfont dalam kode web anda. Poin ini opsional. Jika terpaksa harus demikian, maka sertakanlah opsi nama font lain di CSS anda.

Yap, itu dia poin-poin penting yang perlu kalian perhatikan dalam membuat desain web responsif. Dari semua poin di atas, inti pokoknya sama; menjaga kenyamanan pengunjung.
Sekian dulu tulisan dari saya. Semoga bermanfaat.
Read more

Membuat Desain Web Responsive Part 1


Desain website responsif lebih disukai karena kemampuannya dalam beradaptasi dengan banyak jenis device. Hal ini semakin penting, mengingat jumlah pengguna perangkat mobile semakin meningkat pesat. Jika anda memiliki website, namun belum memiliki desain responsif, anda harus mempertimbangkan untuk membuat desain responsif baru anda.
Ada beberapa hal yang perlu diketahui untuk membuat design website anda responsif. Berikut, kita bahas poin-poinnya. Dan di akhir, kita akan praktekkan dan melihat hasilnya dengan sebuah sampel contoh.

1. Jangan Gunakan <table> Untuk Layout
Ubah desain anda yang bermula dari layout berbasis <table>, dengan layout <div>.

<div class='content'>
    <div class='content-header'>
        header
    </div>
    <div class='content-left'>
        kiri
    </div>
    <div class='content-right'>
        kanan
    </div>
    <div style='clear:both' />
    <div class='content-footer'>
        footer
    </div>
</div>

2. Gunakan ukuran % untuk mengatur lebar layout.
Belum cukup dengan poin sebelumnya, kita juga harus mengatur layoout di atas dengan CSS. Untuk membuat desain website anda responsif, penentuan ukuran sebaiknya tidak dilakukan secara absolut, namun relatif terhadap persentase ukuran browser ataupun ukuran parent element. Khususnya ketika menetukan ukuran width tiap elemen.

3. Secara opsional gunakan unit ukuran relatif untuk teks
Bukan cuma box yang harus diperhatikan, font juga. Agar teks dapat bersesuaian dengan ukuran element parent-nya, ukuran font sebaiknya ditentukan dengan ukuran relatif juga. Untuk ini, kita bisa menggunakan unit relatif %, atau em untuk menyesuaikan dengan pengaturan ukuran font default web browser. Perlu diketahui, 1em = ukuran font standar yang sedang digunakan. Jika kita ingin melihat ukuran font sedikit lebih besar, coba gunakan 1.2em, atau 2em untuk melihat ukuran 2 kali ukuran normal.
font-size: ...

4. Buat layout benar-benar responsif dengan tambahan rule CSS ini
float
Yang agak membingungkan, ketika memulai desain web responsif adalah membuat 2 elemen berdiri beradampingan. Ini dapat dicapai dengan rule float dalam CSS. Kita dapat mengatur yang bagian kiri dengan float:left, dan bagian kanan dengan float:right. Atau, sama-sama float:left juga tidak masalah.

box-sizing
Masalah berikutnya timbul, ketika kita mencoba resize web-browser. Awalnya elemen yang berdampingan tadi menyesuaikan dengan baik; tapi saat ukuran terlalu kecil, salah satu elemen pindah ke bawah. Ini bisa diatasi dengan memberikan rule box-sizing:box-border. Secara default, semua element memiliki properti box-sizing:content-box. Dengan mengganti rule ini, batasan elemen ditentukan oleh bagian tepian/border elemen, bukan dari content yang ada di dalamnya.

clear
Terkadang, elemen lain yang seharusnya berada di bawah tiba-tiba naik ke atas. Meng-overlap di atas elemen yang menggunakan rule float. Untuk menghindari ini, kita buat sebuah element <div> baru dibawahnya dengan menerapkan rule clear:both.

    <div class='content-left'>
        ...
    </div>
    <div class='content-right'>
        ...
    </div>
    <div style='clear:both' />
    ...

 Overall, seperti ini contoh CSS untuk desain responsif HTML pada poin pertama.

<style>
.content{
	max-width:80%;
	margin: 0 auto;
	border:1px solid #999;
}
.content-header, .content-footer{
	background:#DFF;
	width:100%;
}
.content-left{
	height:200px;
	background:#DDD;

	width:50%;
	float:left;
	box-sizing:border-box;
}
.content-right{
	height:200px;
	background:#AAA;

	width:50%;
	float:left;
	box-sizing:border-box;
}
</style>



4. Terapkan rule @media dalam CSS.
Jika ada properti yang ingin dibuat spesial hanya pada ukuran browser tertentu, rule @media bisa digunakan. Sebagai contoh, rule ini akan membuat ukuran .content 100% dari lebar browser saat lebar browser berukuran di bawah atau sama dengan 500px.

@media screen and (max-width: 500px) {
	.content{
		max-width:100%;
	}
}
@media screen and (min-width: 501px) {
	.content{
		max-width:80%;
	}
}
.content{
	margin: 0 auto;
	border:1px solid #999;
}
...


Seluruh kode
Kita gabungkan semuanya jadi satu...

<head>
	<style>
	@media screen and (max-width: 500px) {
		.content{
			max-width:100%;
		}
	}
	@media screen and (min-width: 501px) {
		.content{
			max-width:80%;
		}
	}
	.content{
		margin: 0 auto;
		border:1px solid #999;
	}
	.content-header, .content-footer{
		background:#DFF;
		width:100%;
	}
	.content-left{
		height:200px;
		background:#DDD;
		width:50%;
		float:left;
		box-sizing:border-box;
	}
	.content-right{
		height:200px;
		background:#AAA;
		width:50%;
		float:left;
		box-sizing:border-box;
	}
	</style>
</head>
<div class='content'>
	<div class='content-header'>
		header
	</div>
	<div class='content-left'>
		kiri
	</div>
	<div class='content-right'>
		kanan
	</div>
	<div style='clear:both' />
	<div class='content-footer'>
		footer
	</div>
</div>

Wow, keren bukan?
Sekarang, setelah mengetahui dasar-dasarnya; anda bisa mulai mengembangkan template responsif pertama anda. Atau, modifikasi template terdahulu yang masih anda sukai.
Semoga bermanfaat...
Read more

Membuat Navigasi Halaman (Page Navigation) dengan PHP


Walaupun cuma berisi angka, nyatanya tidak banyak yang bisa membuat page navigation. Karena membuat page navigation tidak semudah membalikkan tangan.

Membuat page naviagtion itu mudah setelah kita tahu bagaimana behavior page navigation yang akan dibuat. Karena ada banyak cara tentang bagaimana page navigation ini bekerja, maka untuk tulisan ini, kita hanya akan membahasa tentang salah satu model saja. Berikut behavior page navigation yang akan kita buat..
  • Setiap page yang sedang dipilih akan berusaha memiliki maksimal 3 sisi buah page disampingnya.
  • Setelah kita membuat 3 page kosong dibagian kiri; Jika di bagian kirinya lagi terdapat >= 1 page lain, selain angka 1; maka sisa page itu akan diganti elipsis ( ... ). Begitu pula jika dibagian kanan; kita harus melihat jumlah halaman totalnya.


Untuk membuat sebuah page, ada beberapa parameter yang harus disediakan.

WritePage($pageStart,$itemCount,$pageCapacity)

pageStart: Halaman yang diinginkan.
itemCount: Jumlah total konten yang dimiliki
pageCapacity : Jumlah konten/item yang ditampung setiap page.
Tahapan awal yang perlu dilakukan adalah mengetahui jumlah page dari parameter yang telah diberikan. Rumusnya adalah...
$pageCount = $itemCount / $pageCapacity;

Sebelum diproses dengan rumus tersebut, itemCount harus dibulatkan(align) menjadi kelipatan pageCapacty. Misal: pageCapacity 10, itemCount 99 --> itemCount diubah jadi 100; pageCapacity 10, itemCount 80 --> itemCount tetap 80; pageCapacity 10, itemCount 81 --> itemCount diubah jadi 90. Rumit? Tenang, saya sudah siapkan kode untuk ini.

function AlignValue($value,$align){
    if($value % $align){
        $value += ($align - ($value % $align));
        return $value;
    }
    else return $value;
}


Jadi, total halaman yang ada adalah: AlignValue (itemCount, pageCapacity) / pageCapacity.
Masih penasaran kenapa harus menggunakan AlignValue() ? bayangkan ada 19 item dengan kapasitas 10 item. Kalau tidak di align; 19 / 10 = 1 ! Padahal kita butuh 2 halaman, lho.

Sekarang, kita sudah bisa mulai membuat page nya; dimulai dari menulis page di bagian kiri dari halaman yang terpilih (pageStart).

1. Jika page pertama dari 3 page sebelum page terpilih (pageStart) adalah 1 atau 2, maka kita langsung saja menulis page navigation secara berurutan. Misal pageStart nya halaman 5 atau 6:
5 > 1 2 3 4 5
6 > 1 2 3 4 5
 
    if ($pageStart-3 <= 2){
        for($p = 1; $p < $pageStart; $p++){
            echo "|$p|";
        }
    }


2. Tapi, jika lebih dari itu, kita harus menulis elipsis. Misal pageStart 7 atau 8.
5 > 1 ... 4 5 6 7
6 > 1 ... 5 6 7 8

    else{
        echo "|1||...|";
        for($p = $pageStart-3; $p < $pageStart; $p++){
            echo "|$p|";
        }
    }

 
3. Bagian kiri beres. Kita tulis dan tandai tebal, di halaman mana kita sekarang.

echo "<b>|$pageStart|</b>";

4. Sekarang tulis page di sebelah kanan pageStart.
Jika halaman terakhir dari 3 page pengikut pageStart berada tepat sebelum page terakhir, atau selebihnya;  kita tulis page langsung tanpa elipsis. Misal pageStart 6, 7 atau 8 dari total (pageCount) berjumlah 10.
6 > 6 7 8 9 10
7 > 7 8 9 10
8 > 8 9 10

    if ($pageStart+3 >= $pageCount-1){
        for($p = $pageStart+1; $p <= $pageCount; $p++){
            echo "|$p|";
        }
    }


5. Tapi, jika tidak; kita perlu membuatkan elipsis. Misalnya pada pageStart 4 atau 5 dari total page 10.
4 > 4 5 6 7 ... 10
5 > 5 6 7 8 ... 10

    else{
        for($p = $pageStart+1; $p <= $pageStart+3; $p++){
            echo "|$p|";
        }
        echo "|...||$pageCount|";
    }


Full code
<?php
function AlignValue($value,$align){
    if($value % $align){
        $value += ($align - ($value % $align));
        return $value;
    }
    else return $value;
}
function WritePage($pageStart,$itemCount,$pageCapacity){
    $itemCount = AlignValue($itemCount,$pageCapacity);
    $pageCount = 0;
    $pageCount = $itemCount / $pageCapacity;
   
    //write before current
    if ($pageStart-3 <= 2){
        for($p = 1; $p < $pageStart; $p++){
            echo "|$p|";
        }
    }
    else{
        echo "|1||...|";
        for($p = $pageStart-3; $p < $pageStart; $p++){
            echo "|$p|";
        }
    }
   
    echo "<b>|$pageStart|</b>";
    //write after current
    if ($pageStart+3 >= $pageCount-1){
        for($p = $pageStart+1; $p <= $pageCount; $p++){
            echo "|$p|";
        }
    }
    else{
        for($p = $pageStart+1; $p <= $pageStart+3; $p++){
            echo "|$p|";
        }
        echo "|...||$pageCount|";
    }
}

WritePage(6,121,10);
?>


Bagaimana dengan link URL untuk navigasi ?
Kodenya hanya perlu dimodifikasi sedikit. Dengan tambahan parameter $cont (container) dan $link (url/link). Format page navigation yang saya buat adalah:

<li><a href=’?page=halaman’>halaman</a></li>

Dengan fungsi baru yang telah dimodifikasi berikut ini, kita bisa memperoleh format seperti di atas. Anda sendiri pasti bisa membuat fungsi serupa ini. Hanya sedikit tambahan str_replace() pada fungsi sebelumnya. Jika ada yang kurang, coba modifikasi CSS nya.

XyzWritePage(1,1000,16,"<li>[@link]</li>","<a href='?page=[@page]'>[@page]</a>");

function XyzAlignValue($value,$align){
    if($value % $align){
        $value += ($align - ($value % $align));
        return $value;
    }
    else return $value;
}
function XyzWritePage($pageStart,$itemCount,$pageCapacity,$cont,$link){
    $html='';
    $itemCount = XyzAlignValue($itemCount,$pageCapacity);
    $pageCount = 0;
    $pageCount = $itemCount / $pageCapacity;
    //write before current
    if ($pageStart-3 <= 2){
        for($p = 1; $p < $pageStart; $p++){
            //echo "$p,";
            $l = str_replace('[@page]',$p,$link);
            $html = $html . str_replace('[@link]',$l,$cont);
        }
    }
    else{
        //echo "1,...,";
        $l = str_replace('[@page]',1,$link);
        $html = $html . str_replace('[@link]',$l,$cont);
        $html = $html . str_replace('[@link]','...',$cont);
        for($p = $pageStart-3; $p < $pageStart; $p++){
            //echo "$p,";
            $l = str_replace('[@page]',$p,$link);
            $html = $html . str_replace('[@link]',$l,$cont);
        }
    }
    //echo "$pageStart";
    $html = $html . str_replace('[@link]',$pageStart,$cont);
    //write after current
    if ($pageStart+3 >= $pageCount-1){
        for($p = $pageStart+1; $p <= $pageCount; $p++){
            //echo "$p,";
            $l = str_replace('[@page]',$p,$link);
            $html = $html . str_replace('[@link]',$l,$cont);
        }
    }
    else{
        for($p = $pageStart+1; $p <= $pageStart+3; $p++){
            //echo "$p,";
            $l = str_replace('[@page]',$p,$link);
            $html = $html . str_replace('[@link]',$l,$cont);
        }
        //echo "...,$pageCount";
        $html = $html . str_replace('[@link]','...',$cont);
        $l = str_replace('[@page]',$pageCount,$link);
        $html = $html . str_replace('[@link]',$l,$cont);
    }
    return $html;

}

Demo?
Klik www.lomba.asia
Read more

Sabtu, 22 Oktober 2016

Arti Buffer Dalam Dunia Pemrograman


Saat awal mulai menggerakkan tangan, menulis serangkaian kode, kita sering menghadapi kesulitan. Salah satu sumber kesulitan tersebut adalah banyaknya istilah baru yang muncul dan lewat di telinga kita. Kita merasa asing dengan istilah itu, bahkan saat membuka kamus pun terkadang maksud dari kata itu seperti ngaco dan tidak relevan dengan masalah yang sedang kita hadapi.

Salah satu istilah ambigu dalam pemrograman adalah "Buffer". Jika diterjemahkan, arti kata buffer adalah "penyanga". Tentu di awal kita bingung, apa yang disangga? dan apa hubungannya dengan kode yang kita tulis?

Tidak perlu bingung, bahasa inggris mah gitu bahasanya. Kita tak perlu memahami artinya, tapi cukup mengetahui maksudnya. Jangan sampai salah mengartikan antara dua kata dengan interpretasi sendiri; seperti "tidak apa-apa" dan "no what-what" :v

Dalam pemrograman, buffer adalah sebutan untuk tempat penyimpanan data sementara. Seperti saat memutar video, video player akan mengalokasikan beberapa MB memori untuk menyimpan video dalam kurun waktu tertentu sebelum dapat diputar. Atau, ketika kita mengetik keyboard, semua karakter disimpan dalam memori yang telah dialokasikan; sebelum disampaikan ke monitor.

Mirip dengan data sementara. Tapi yang membedakan adalah, buffer digunakan menjadi media perantara. Itulah mungkin kenapa buffer disebut sebagai penyangga. Buffer seperti gelas; meski kita bisa minum langsung dari galon, lebih mudah jika diambil sebagian-sebagian melalui gelas.

contoh sederhana buffer dalam pemrograman adalah saat kita menggunakan scanf(). Buffer berperan untuk menyangga data hasil input, sebelum akhirnya diproses dan dicetak.

char buffer[200];
int main(){
    scanf("%s",buffer);
    strupr(buffer);
    printf(buffer);
}


Biasanya buffer diperlukan ketika sumber data kurang efektif untuk dibaca berulang-ulang, atau karena tidak mungkin untuk dibaca ulang, atau bia juga karena ada banyak sumber data sejenis yang harus dipilah-pilah. Namun disamping itu data yang telah terbaca harus diproses dengan frekuensi yang besar.


int
Read more

Niat Cari Duit Online ? Jangan Pakai Hosting Gratisan !


Beberapa waktu yang lalu, saya banyak menghabiskan waktu saya untuk menyelesaikan project yang benar-benar project serius pertama saya. Ya, saya akui, selama beberapa tahun, belum satupun koding saya dikerjakan dengan serius. Cuma buat main-main.

Sebenarnya niat saya cukup kuat saat itu, namun keraguan itu masih tetap ada. Sayapun mengikuti keraguan tersebut, dan itu membuat saya memilih hosting gratisan dari h*******r.c*.i*. Pikir saya, harga domain yang tinggi sebagai modal sepertinya tak perlu dibebani lagi dengan biaya sewa hosting.

Selang beberapa hari, saya mulai optimis untuk membelikan domain TLD dengan tetap bergantung pada hosting gratisan. Dengan pengunjung yang sangat fluktuatif, tentu merogoh kocek tidaklah terlalu sulit. Tapi, ketika rencana membeli domain di esok hari itu sudah benar-benar kuat, ABRA KADABRA. Your account has been suspended. Alasannya, website saya sudah lebih dari 32 kali memakai resource CPU tidak wajar. Hah?
Alasan yang yang tak masuk akal, kalau pakai CMS wordpress sih masih mungkin. Lha ini? cuma template sendiri yang size nya gak sampai 50 KB. Tapi, setelah saya lihat spec lengkap hostingnya; ada benarnya juga sih. What? RAM nya cuma 256 MB?. Pelajaran baru: lihat spec komputer, terutama pada RAM nya.

Sayapun frustasi, apalagi hanya karena pekerjaan ini, saya harus menghilang dari dunia kampus lebih dari sebulan; di saat yang bersamaan, saya nekat tidak mengerjakan laporan PKL, saat semua rombongan kelompok telah sampai di bab 4-5. WTF. Astaghfirullah..

Sayapun konsultasi dengan teman-teman dari grup PHP Indonesia. Ternyata tidak banyak yang bernasib sama sepeti saya. Gundah, tidak ada teman curhat pula. Hahaha..
Beberapa saat kemudian, ada member yang menyarankan salah satu hosting, yang katanya murah. Saya lihat, 10.000 per bulan.
"Ini sih standar", pikir saya yang waktu itu masih berpikir bahwa kontrak minimum sewa hosting minimum satu semester untuk harga rentang standar dan 1 tahun untuk rentang harga sewa yang murah. Tapi ternyata saya salah, di r***c***rs******n ini, saya bisa menyewa minimal satu bulan saja; padahal rentang harga sewa disini menurut saya relatif murah. Apalagi ditambah dengan tawaran unlimited bandwith dan space-nya.

Sayapun kembali optimis. Saya hancurkan gundah saya, dan memutuskan untuk menyewa hosting. Em, sewa 3 bulan dulu lah. Keraguan itu masih tetap ada, tapi setidaknya saya sudah sedikit berani berkorban saat kehancuran itu telah terjadi. Puitis amat, yah...

So, bagi teman-teman, jika memang serius memanfaatkan website untuk mencari profit; jangan gunakan website gratisan, ya. Lihat saja di Google, ternyata sudah banyak korban yang telah tergiur dengan tawaran hosting gratisan. Semuanya berakhir sama, SUSPENDED.
Read more

Jumat, 21 Oktober 2016

Kapan Harus Menggunakan Heksadesimal Dalam Pemrograman ?


Sistem bilangan biner komputer yang seringkali mempersulit pemrogram. Sehingga bilangan yang direpresentasikan dalam bentuk biner tersebut perlu direpresentasikan dalam bentuk lain. Bentuk heksadesimal inilah yang salah satu yang umum digunakan untuk menyederhanakan representasi dan memudahkan keterbacaan kode.

Bilangan yang ditulis dalam bentuk biner lebih mudah digunakan saat hendak melakukan pemrograman yang erat kaitannya dengan fungsi logika, karena setiap digit akan nyata terlihat lebih jelas saat akan digunakan. Namun selanjutnya programmer akan kesulitan jika ternyata bilangan tersebut juga harus diproses secara matematis, ini karena bilangan biner sulit dan kurang efisien untuk dikonversikan secara manual ke dalam bentuk sistem bilangan lain.

Heksadesimal menjawab permasalahan tersebut. Sistem bilangan ini memiliki basis 16. Basis ini memliki bentuk dasar perpangkatan yang sejenis dengan bilangan biner (24 = 16). Dengan heksadesimal, setiap digit angka yang ditulis dapat merepresentasikan 4 digit bilangan biner. Tentu saja ini akan sangat membantu programmer yang berkutat dan menguras pikirannya untuk mengolah bilangan secara logika dan matematika. Berikut Ini adalah 16 digit representasi heksadesimal beserta persamaan representasinya dengan representasi biner dan desimal.

Heksadesimal
Biner
Desimal
0
0000
0
1
0001
1
2
0010
2
3
0011
3
4
0100
4
5
0101
5
6
0110
6
7
0111
7
8
1000
8
9
1001
9
A
1010
10
B
1011
11
C
1100
12
D
1101
13
E
1110
14
F
1111
15

Secara mendasar, semua sistem bilangan akan memiliki bentuk seperti ini..
m x bn + m x bn-1 + ... + m x b2 + m x b1 + m x b0
Dimana:
m = representasi digit dalam desimal
b = basis bilangan
n = pangkat yang menentukan bobot bilangan
Karena heksadesimal berbasis 16, maka angka FE12 dapat dikonversi seperti ini:

  FE12 => 15-14-1-2
= 15 x 163 + 14 x 162 + 1 x 161 + 2 x 15160
= ?

Penggunaan heksadesimal biasanya sering diterapkan pada akses memori dan manipulasi bit (bitwise operation). Dalam bitwise operation Angka heksadesimal dapat menyederhanakan representasi biner lebih mudah.

Katakanlah bilangan biner tersebut ditulis FFE1, dengan melihat tabel di atas kita bisa langsung menginterpretasikannya sebagai 1111 1111 1110 0001. Apalagi kalau kita hafal, akan sangat mudah menginterpretasikan maksud dari bilangan heksadesimal. Bayangkan jika bilangan ini direpresentasikan dengan desimal.

1111 1111 1110 0001(biner) = 65505(desimal).

Sulit kan membayangkan bentuk bit-bit nya?

Sementara itu, untuk mengakses memori, alamat yang digunakan juga lebih sering menggunakan heksadesimal daripada heksadesimal. Ini karena komputer memiliki sistem bilangan dasar biner, sehingga kurang efektif untuk membuat pengalamatan berbasis desimal. Heksadesimal lebih efektif karena dekat dengan sistem biner, karena memiliki basis angka berkelipatan 2.

Alasan lain juga karena sistem kerja memori masih erat kaitannya dengan mekanisme bitwise. Jadi jangan heran. Misalnya saja dalam mekanisme virtual memory yang sedang banyak diterapkan sekarang ini. Sebuah data 32-bit digunakan untuk menyimpan alamat physical (20 bit bagian kiri) dan dan permission (12 bit bagian kanan) dari alamat tersebut. Selanjutnya, alamat physical yang ditunjuk dengan menganggap 12-bit permission sebagai 0. Dalam mekanisme ini memori juga dibagi menjadi potongan 0x1000 (4096 byte).

0000 0000 0000 0000 0000 0000 0000 0000 = 0x00000000
0000 0000 0000 0000 0001 0000 0000 0000 = 0x00010000
0000 0000 0000 0000 0010 0000 0000 0000 = 0x00020000
0000 0000 0000 0000 0011 0000 0000 0000 = 0x00030000

Bayangkan jika menggunakan desimal...
0000 0000 0000 0000 0000 0000 0000 0000 = 0
0000 0000 0000 0000 0001 0000 0000 0000 = 4096
0000 0000 0000 0000 0010 0000 0000 0000 = 8192
0000 0000 0000 0000 0011 0000 0000 0000 = 12288

Merepotkan bukan?
Masih banyak alasan lain untuk lebih baik menggunakan heksadesimal dalam beberapa keperluan. Tapi, sepertinya saya sudah capek ngetiknya. :-)

Memang sebenarnya heksadesimal tidak diperuntukkan untuk menunjukkan jumlah yang masih berhubungan dengan kegiatan manusiawi, misalnya jumlah karyawan, jumlah pengguna online. Penggunaan heksadesimal lebih ke arah yang lebih internal ke komputer, misalnya harddisk, memori, ukuran data, dll.

TIPS: Saat bertemu bilangan heksadesimal, tak perlu mengonversi nilainya ke desimal sebelum mengolahnya. Jika tidak tahu cara menghitung dengan basis angka heksadesimal, gunakanlah program kalkulator.
Read more

Mengapa Fungsi Main Memiliki Bentuk Berbeda-beda ?


Ada banyak cara untuk mengawali menulis kode pertama.

int main(int argc, char **argv){
    ...
}

void main(int argc, char **argv){
    ...
}

int main(){
    ...
}
void main(){
    ...
}
Bahkan mungkin dengan cara yang lain lagi.

Mengapa demikian, dan mengapa program dapat di-build dengan normal?
Tidak  seperti fungsi lain, fungsi main adalah fungsi spesial dalam sebuah struktur program. Fungsi main menjadi titik awal dari sebuah program untuk melakukan kerjanya.

Sebagai titik awal, tentu saja fungsi ini harus memiliki wewenang untuk mengatur subfungsi dibawahnya. Tapi juga harus bertanggung jawab menginterpretasikan kemauan pengguna dalam menjalankan program.

Model eksekusi program klasik melalui terminal sudah mulai banyak ditinggalkan, namun kompatibilitasnya tetap terjaga. Meski program tidak dijalankan dari terminal/command line, program akan sellu menerima perintah eksekusi dalam bentuk command line. Perintah ini adalah argv yang ada di fungsi main umum program C. Secara otomatis, sistem operasi akan mengarahkan command dan argumen dari terminal ke sini. Ketika program dijalankan tanpa melalui terminal, biasanya command akan berisi path dan nama program, tanpa argumen.

Struktur fungsi main sebenarnya tidak ada standar yang mengatur. Sehingga beda lingkungan pemrograman, beda pula bentuknya. Tapi secara umum, bentuknya tidak jauh dari bentuk berikut.

int main(int argc, char **argv){
    ...
}

Misalnya saja pada pemrograman GUI Windows, bentuk fungsi main seperti berikut ini.

int WINAPI WinMain(
    HINSTANCE   hInstance,
    HINSTANCE   hPrevInstance,
    PWSTR       lpCmdLine,
    int         nCmdShow
    );

Ini karena Windows melakukan kerja yang berbeda untuk program console dan GUI. Namun di Linux, baik GUI ataupun console, bentuknya sama saja. Jadi, pada dasarnya, bentuk fungsi main ditentukan oleh bagaimana sistem operasi mengirimkan parameter ke program kita.

Bagaimanapun, kita dapat mengabaikan argumen-argumen tersebut, dan bahkan tidak mengembalikan return value, bila anda ingin demikian.

void main(){
    ...
}

Tidak masalah, program anda akan berjalan normal. Ini karena fungsi main istimewa. Compiler sudah mempertimbangkan dari awal, karena setiap lingkungan pemrograman akan memiliki model penyampaian argumen berbeda. Sehingga kita diberi kebebasan untuk memilih bentuk fungsi main. Semua argumen fungsi secara opsional dapat diolah ataupun diabaikan.
Read more

Kamis, 20 Oktober 2016

Inilah Beberapa Kegunaan Bitwise Operator


Bahasa C memiliki banyak operator yang bisa kita gunakan untuk berbagai keperluan. Salah satunya adalah kelompok bitwise operator. Sayangnya, programmer awam masih belum banyak tahu kegunaannya, sehingga pendayagunaannya pun masih terbatas.

Jadi, sekarang tulisan ini akan menunjukkan beberapa trik terkait dengan penggunaan operator tersebut di C.

Yang pertama adalah operator shift left dan shift right. Operator ini digunakan untuk menggeser bit ke arah kiri atau kanan.
 
// 1        00000001

// 1<<1     00000010

// 1        00000001
// 1<<3     00001000

// 8        00001000
// 8<<1     00010000 

// 8        00001000
// 8>>1     00000100 


// 8        00001000
// 8>>4     00000000 

// 8        00001000
// 8<<5     00000000 

Kelompok operator ini ternyata dapat digunakan untuk melakukan perkalian dan pembagian cepat dengan nilai pembagi berkelipatan pangkat dua (1, 2, 4, 8, 16, 32, 64, ...). Dokumentasi intel menunjukkan bahwa instruksi perkalian dan pembagian membutuhkan CPU clock lebih besar dari instruksi aritmatika dan logika lainnya.
http://www.penguin.cz/~literakl/intel/s.html#SHL
http://www.penguin.cz/~literakl/intel/m.html#MUL

Jika kita mengembangkan program yang fokus pada performa, gunakanlah kedua operator ini jika bertemu perkalian atau pembagian degan bilangan berkelipatan pangkat 2.

10 x 2^0 = 10 x 1  = 10 << 0
10 x 2^1 = 10 x 2  = 10 << 1
10 x 2^2 = 10 x 4  = 10 << 2
10 x 2^3 = 10 x 8  = 10 << 3
10 x 2^4 = 10 x 16 = 10 << 4
dst...
10 / 2^0 = 10 / 1  = 10 >> 0
10 / 2^1 = 10 / 2  = 10 >> 1
10 / 2^2 = 10 / 4  = 10 >> 2
10 / 2^3 = 10 / 8  = 10 >> 3
10 / 2^4 = 10 / 16 = 10 >> 4


Untuk menghemat disk dan memori space, seringkali status di representasikan dalam bentuk BOOLEAN (hanya memiliki 2 kemungkinan: benarr/salah) berukuran 1 bit. Keadaan benar/true diwakili oleh 1 dan salah diwakili nilai 0. Dalam setiap byte data terdapat banyak bit yang dapat digunakan untuk menyimpan state/keadaan tertentu. Untuk menangani nilai boolean itu tadi, kita harus menggunakan banyak operator logika.

Sebagai contoh, saat ingin memeriksa kodisi nilai bit-3 (dihitung mulai 0 dr kanan) pada sebuah data byte; maka perlu dilakukan operasi semcam berikut ini.

// Diketahui:
// 15       00001111
// 8        00001000
// 1        00000001
// 1<<3     00001000


//Contoh...

// 8 & (1<<3)
// 00001000
// 00001000
// hasilnya..
// 00001000


//Contoh lain...
// 15 & (1<<3)
// 00001111
// 00001000
// hasilnya..
// 00001000

// Dalam pemrograman, semua nilai BUKAN 0 memiliki arti TRUE

Sehingga, untuk memeriksa state bit dalam suatu data byte, kita bisa melakukan cara seperti ini. Jika return value BUKAN 0, artinya true atau benar bahwa bit yang ditentukan oleh argumen posisi bernilai 1.
int cek_state(char state, char posisi){
    return state & (1 << posisi);
}


Kemudian, ketika hendak meng-set bit (dari 0 ke 1), operator bitwise  | (OR) adalah yang harus berperan. Misal, kita akan set bit-3(urutan ke empat dr kanan)

// Diketahui:
// 0        00000000
// 1        00000001
// 1<<3     00001000

// Contoh...

// 0 | (1<<3)
// 00000000
// 00001000
// di OR hasilnya..
// 00001000

// Contoh lain...
// 15 | (1<<3)
// 00001111
// 00001000
// di OR hasilnya..
// 00001111


Kodenya dalam C bisa ditulis seperti berikut:


char set_state(char state, char posisi){
    return state | (1 << posisi);
}


Berbeda lagi ketika hendak meng-unset state (dari 1 ke 0). Maka, perlu satu lagi bitwise operator pembantu, yaitu negate ( ~ ).
// Diketahui:
// 0        00000000
// 8        00001000
// 1        00000001
// 1<<3     00001000
// ~(1<<3)  11110111

// Contoh...

// 8 & ~(1<<3)
// 00001000
// 11110111
// di AND hasilnya..
// 00000000

// Contoh lain...
// 15 & (1<<3)
// 00001111
// 11110111
// di AND hasilnya..
// 00000111


Sehingga kode untuk unset bit harus seperti ini:
char unset_state(char state, char posisi){
    return state & ~(1 << posisi);
}


 Masih bingung ya? Jangan kawatir, ambil sebuah pensil dan gambarkan bagaimana deretan biner dikepala anda. Coba berikan perlakuan bitwise pada bit tersebut dan gambar hasilnya. Jika tetap masih bingung, buka buku matematika SMA anda. :)
Read more