Archive for the ‘ Programming ’ Category

Algoritma Pemrograman – Membagi Nominal Ke Pecahan Menggunakan PHP

Kali ini saya iseng-iseng menulis blog tentang algoritma. Saya juga iseng-iseng mengerjakan salah satu soal pada algoritma pemrograman menggunakan PHP, yaitu bagaimana cara memecah nominal sejumlah uang menjadi pecahan uang (secara fisik). Misal ada uang  Rp 2500, maka uang tersebut terbagi menjadi uang apa saja? Secara gampang kita akan menjawab 1 lembar 2 ribuan dan 1 koin 5 ratus.  Tapi bagaimana menerjemahkan ke dalam bahasa pemrograman? Saya akan mencoba memecahkannya menggunakan PHP.

Kode PHP-nya kurang lebih sebagai berikut:

<?php
$duit = array(100000, 50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 25, 10, 5, 1);
$nom = 98875;
echo "<h4>Nominal : " . $nom . "</h4>";
for ($i = 0; $i < count($duit); $i++) {
 if ($nom % $duit[$i] < $nom) {
 echo floor($nom / $duit[$i]) . " -> " . $duit[$i] . "<br/>";
 $nom = $nom % $duit[$i];
 }
}
?>

Oke, kita bahas kode diatas.

$duit = array(100000, 50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 25, 10, 5, 1);
$nom = 98875;
echo "<h4>Nominal : " . $nom . "</h4>";
  1. $duit berisi array dari semua uang yang ada di negara kita, disini saya buat sampai 1 Rupiah.
  2. $nom adalah nominal uang yang akan kita pecah.
  3. echo … Menampilkan Nominal uang yang akan dipecah.
for ($i = 0; $i < count($duit); $i++) {
 if ($nom % $duit[$i] < $nom) {
 echo floor($nom / $duit[$i]) . " -> " . $duit[$i] . "<br/>";
 $nom = $nom % $duit[$i];
 }
}

Disini menggunakan looping (for) pada array $duit untuk melakukan cek terhadap nominal, jadi lopping akan meng-eksekusi sebanyak jumlah pecahan uang (15 kali). Kemudian dicocokkan dengan nominal, jika sisa pembagian (modulo/modulus) dengan uang di array pertama lebih kecil, maka akan dilanjutkan ke array berikutnya dan seterusnya sampai pencocokan selesai. Pencocokan ini dimulai dari uang yang paling besar. Sehingga cara kerjanya seperti ini:

Misal Nominalnya adalah 98875.

  • Cek apakah modulus (98875/100000) < 98875? Tidak, maka akan dilanjutkan ke Uang berikutnya tanpa mencetak tulisan.
  • Cek apakah modulus (98875/50000) < 98875? Ya, hasil bagi=1 dan sisa=48875, cetak 1 x 50000. Simpan sisa ke $nom.
  • Cek apakah modulus (48875/20000) < 48875? Ya, hasil bagi=2 dan sisa=8875, cetak 2 x 20000. Simpan sisa ke $nom.
  • Cek apakah modulus (8875/10000) < 8875? Tidak, Lanjut ke Uang berikutnya. $nom masih tetap.
  • Cek apakah modulus (8875/5000) < 8875? Ya, hasil bagi=1 dan sisa=3875. Cetak 1 x 5000. Simpan sisa ke $nom.
  • Cek apakah modulus (3875/2000) < 3875? Ya, hasil bagi=1 dan sisa=1875. Cetak 1 x 2000. Simpan sisa ke $nom.
  • Cek apakah modulus (1875/1000) < 1875? Ya, hasil bagi=1 dan sisa=875. Cetak 1 x 1000. Simpan sisa ke $nom.
  • Cek apakah modulus (875/500) < 875? Ya, hasil bagi=1 dan sisa=375. Cetak 1 x 500. Simpan sisa ke $nom.
  • Cek apakah modulus (375/200) < 375? Ya, hasil bagi=1 dan sisa=175. Cetak 1 x 200. Simpan sisa ke $nom.
  • Cek apakah modulus (175/100) < 175? Ya, hasil bagi=1 dan sisa=75. Cetak 1 x 100. Simpan sisa ke $nom.
  • Cek apakah modulus (75/50) < 75? Ya, hasil bagi=1 dan sisa=25. Cetak 1 x 50. Simpan sisa ke $nom.
  • Cek apakah modulus (25/25) < 25? Ya, hasil bagi=1 dan sisa=0. Cetak 1 x 25. Simpan sisa ke $nom.
  • Karena nilai $nom adalah 0, maka Uang berikutnya pasti tidak akan muncul.

Penasaran dengan hasilnya? Silahkan dicoba sendiri. Semoga bermanfaat.

PHP Direct Printing Printer Dot Matrix (LX-300)

Tidak diragukan lagi, direct printing masih menjadi andalan untuk urusan cetak-mencetak, terutama untuk program/aplikasi POS. Karena aplikasi ini membutuhkan kecepatan dalam melakukan cetak dokumen/struk.

Barusan ngoprek dan eksperimen dengan VB.Net untuk cetak langsung ke printer dot matrix tanpa spooling. Dan ternyata caranya hanya dengan meng-copy file temporary ke path printer (yang sudah disharing).

Bermodalkan teknik tersebut, saya coba terapkan di PHP dengan teknik yang sama dan berhasil.

Mudah-mudahan bermanfaat bagi teman-teman disini.


<?php
$tmpdir = sys_get_temp_dir();   # ambil direktori temporary untuk simpan file.
$file =  tempnam($tmpdir, 'ctk');  # nama file temporary yang akan dicetak
$handle = fopen($file, 'w');
$condensed = Chr(27) . Chr(33) . Chr(4);
$bold1 = Chr(27) . Chr(69);
$bold0 = Chr(27) . Chr(70);
$initialized = chr(27).chr(64);
$condensed1 = chr(15);
$condensed0 = chr(18);
$Data  = $initialized;
$Data .= $condensed1;
$Data .= "==========================\n";
$Data .= "|     ".$bold1."OFIDZ MAJEZTY".$bold0."      |\n";
$Data .= "==========================\n";
$Data .= "Ofidz Majezty is here\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "We Love PHP Indonesia\n";
$Data .= "--------------------------\n";
fwrite($handle, $Data);
fclose($handle);
copy($file, "//localhost/xprinter");  # Lakukan cetak
unlink($file);
?>

Jangan lupa Printer yang akan digunakan untuk men-cetak di sharing terlebih dahulu. Ganti ‘localhost’ menjadi IP komputer dimana printer yang tadi disharing berada. “xprinter” adalah nama sharing printer.
Saya belum mencoba di jaringan LAN, baru dioba di localhost.
Untuk Escape Code akan saya posting dikemudian hari.

Jika ada masalah dengan printer pastikan printer bisa diakses dari komputer server apache/php, lakukan-langkah berikut ini:

1. Pada komputer server apache/php buka run, ketik \\ip_komputer_printer.
2. Duoble klik pada icon nama printer yg dimaksud. (nama ini yg nantinya digunakan untuk koneksi di php).
3. Jika driver printer blm terinstal maka windows akan otomatis melakukan instalasi.
4. Jika driver sudah terinstal maka akan muncul window status print.
5. Lakukan test print ke printer tersebut (anda pasti tahu caranya).
6. Jika sudah berhasil melakukan test print dari komputer server, maka printer sudah siap untuk digunakan.

UPDATES

Berhubung banyak permintaan mengenai ESC Code, sekarang saya upload kode nya. Semoga bermanfaat.

https://www.dropbox.com/s/g2vpooaubty1ckp/escode.txt?dl=0

Silahkan buka menggunakan notepad, jika hasilnya berantakan, ganti font pada notepad menjadi TERMINAL.

PHP MySQL Compare/Benchmark, PDO vs Mysql vs Mysqli OOP vs Mysqli Procedural

Saat ini saya akan develop aplikasi yang mature dan dapat diandalkan, sehingga saya mencari tahu cara yang terbaik untuk melakukan koneksi dan query terhadap Database Mysql. Saat ini yang tersedia (bawaan) dari PHP ada 3, yaitu koneksi mysql biasa (biasa disebut Raw Mysql, contoh mysql_connect()), PDO (PHP Data Object) dan Mysqli (OOP dan Procedural). Disamping ketiganya masih banyak lagi aplikasi 3rd party yang dapat digunakan untuk melakukan koneksi ke database Mysql seperti Doctrine (ORM) dkk.

Setelah mencari tahu di internet, kebanyakan dari hasil Benchmark Raw Mysql yang menang. Sehingga saya juga tertarik untuk melakukan perbandingan mana yang paling cepat. Cara yang saya gunakan disini adalah, PHP melakukan koneksi dan query menggunakan looping tanpa menampilkan data hasil query ke halaman website. Mungkin kedepannya saya juga akan melakukan komparasi dengan cara lain, yaitu berapa waktu yg dibutuhkan untuk melakukan query pada data yang besar.

Oke langsung saja saya jabarkan scriptnya disini.

Listing Code mysql_compare.php

<?
/* File name : mysql_compare.php
 * Author : ofidz
 * Email : offiedz@majezty
 * Web : mocopat.wordpress.com
 */
?>
<html>
 <style>
 input {
 font-family: courier;
 text-align: right;
 }
 </style>
 <body style="font-family: courier;">

<table>
 <tr><td align="right">Running time : </td><td><input id="running" value='0' size="10"></td><td align="center">detik</td><td align="center">qry/dtk</td></tr>
 <tr style="background-color: bisque;"><td align="right">PDO Process : </td><td><input id="pdo" value='0' size="10"></td><td><input id="pdt"></td><td><input id="avgpdo" value='0' size="7"></td></tr>
 <tr style="background-color:lightcyan ;"><td align="right">Raw Process : </td><td><input id="raw" value='0' size="10"></td><td><input id="rdt"></td><td><input id="avgraw" value='0' size="7"></td></tr>
 <tr style='background-color: lightgreen;'><td align="right">Mysqli OOP Process : </td><td><input id="sqli" value='0' size="10"></td><td><input id="sqlit"></td><td><input id="avgsqli" value='0' size="7"></td></tr>
 <tr style='background-color: lavender;'><td align="right">Mysqli Proc Process : </td><td><input id="sqlip" value='0' size="10"></td><td><input id="sqlipt"></td><td><input id="avgsqlip" value='0' size="7"></td></tr>
 </table>
 <script>
 var milisec = 0
 var seconds = 0
 document.getElementById('running').value='0'
 function display(){
 if (milisec >= 9){
 milisec = 0
 seconds += 1
 }
 else
 milisec += 1
 document.getElementById('running').value=seconds+"."+milisec+" detik"
 t = setTimeout("display()",100)
 }
 display()
 </script>
 <?
 set_time_limit(3600);
 $data = 1000;
 $server = "localhost";
 $user = "root";
 $pass = "";
 $db = "nwind";
 $sql = "SELECT * FROM order_details ";
 # Function

function xtime($start) {
 return microtime(true) - $start;
 }

# Begin Test PDO

function pdo_test($server, $db, $user, $pass, $data, $sql) {

$start = microtime(true);
 for ($i = 1; $i <= $data; ++$i) {

try {
 $conn = new PDO("mysql:host=$server;dbname=$db", $user, $pass);
 } catch (PDOException $e) {
 echo 'Connection failed: ' . $e->getMessage() . "\n";
 }

$conn->query($sql);
 echo "<script>document.getElementById('pdo').value='$i/$data';</script>";
 echo "<script>document.getElementById('pdt').value='" . xtime($start) . "';</script>";
 echo "<script>document.getElementById('avgpdo').value='" . number_format($i / xtime($start), 2, ',', '') . "';</script>";
 $conn = null;
 }
 echo "<tr style='background: bisque;'><td align='right'>PDO time : </td><td>" . xtime($start) . "</td></tr>";
 echo "<br/>";
 }

# Begin mysql_* Test

function mysql_test($server, $db, $user, $pass, $data, $sql) {
 $start = microtime(true);

for ($i = 1; $i <= $data; ++$i) {
 $conn = mysql_connect($server, $user, $pass);
 mysql_select_db($db);
 mysql_query($sql);
 echo "<script>document.getElementById('raw').value='$i/$data';</script>";
 echo "<script>document.getElementById('rdt').value='" . xtime($start) . "';</script>";
 echo "<script>document.getElementById('avgraw').value='" . number_format($i / xtime($start), 2, ',', '') . "';</script>";
 mysql_close($conn);
 }

echo "<tr style='background-color:lightcyan ;'><td align='right'>Raw time : </td><td>" . xtime($start) . "</td></tr>";
 }

# Mysqli OOP test

function mysqli_oop_test($server, $db, $user, $pass, $data, $sql) {
 $start = microtime(true);
 for ($i = 1; $i <= $data; ++$i) {
 $mysqli = new mysqli($server, $user, $pass, $db);
 $mysqli->query($sql);
 echo "<script>document.getElementById('sqli').value='$i/$data';</script>";
 echo "<script>document.getElementById('sqlit').value='" . xtime($start) . "';</script>";
 echo "<script>document.getElementById('avgsqli').value='" . number_format($i / xtime($start), 2, ',', '') . "';</script>";
 $mysqli->close();
 }
 echo "<tr style='background: lightgreen;'><td align='right'>Mysqli OOP time : </td><td>" . xtime($start) . "</td></tr>";
 }

# Mysqli Procedural Test

function mysqli_proc_test($server, $db, $user, $pass, $data, $sql) {
 $start = microtime(true);
 for ($i = 1; $i <= $data; ++$i) {
 $mysqli = mysqli_connect($server, $user, $pass, $db);
 mysqli_query($mysqli, $sql);
 echo "<script>document.getElementById('sqlip').value='$i/$data';</script>";
 echo "<script>document.getElementById('sqlipt').value='" . xtime($start) . "';</script>";
 echo "<script>document.getElementById('avgsqlip').value='" . number_format($i / xtime($start), 2, ',', '') . "';</script>";
 mysqli_close($mysqli);
 }
 echo "<tr style='background: lavender;'><td align='right'>Mysqli Proc time : </td><td>" . xtime($start) . "</td></tr>";
 }

 # Jumlah baris data
 function jml_row($server,$user,$pass,$db,$sql){
 $conn = mysql_connect($server,$user,$pass);
 mysql_selectdb($db);
 $xSql = mysql_query($sql);
 return mysql_num_rows($xSql);
 mysql_close($conn);
 }
 ?>
 <table>
 <tr><td align='right'><b>Result :</b></td><td><?= $data . " x ". jml_row($server, $user, $pass, $db, $sql)." row(s) execution"; ?></td></tr>
 <?
 pdo_test($server, $db, $user, $pass, $data, $sql);
 mysql_test($server, $db, $user, $pass, $data, $sql);
 mysqli_oop_test($server, $db, $user, $pass, $data, $sql);
 mysqli_proc_test($server, $db, $user, $pass, $data, $sql);
 ?>
 </table>
 <script>
 clearTimeout(t);
 </script>
 </body>
</html>

Pada script diatas, masing-masing driver menggunakan function, supaya kita lebih mudah dalam menempatkan driver yang lebih dulu akan dijalankan. Jumlah query yang akan dijalankan juga dapat disetting dengan mengganti nilai pada variabel $data. Berikut contoh hasil benchmark yang saya lakukan.

Software dan Hardware yang saya gunakan pada saat benchmark.

  • OS : Windows 7
  • Laptop Acer 4752G
  • Prosesor : Intel Core i3-2330
  • RAM : Kingston 2GB
  • Hardisk : Seagate 500GB
  • VGA NVIDIA GeForce GT 520M 1GB
  • Browser : Chrome 17
  • MySQL :  5.0.8
  • PHP : 5.3.8

Jika anda pernah melakukan benchmark juga, silahkan share disini. Saya juga minta pendapat anda mengenai script yang saya pakai untuk benchmark, mungkin kurang fair atau bagaimana, silahkan diluruskan jika kurang fair. Terima kasih.