Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, August 27, 2014

Perbedaan quantifier dalam Regex

Terdapat tiga modus quantifier dalam regex, yang pertama adalah greedy, kedua adalah reluctant, dan yang ketiga adalah possessive. Berikut penjelasannya

13

Dalam modus greedy,  matcher pertama-tama  nge-match seluruh string. Jika tidak ditemukan yang match, dia akan melakukan backtracking dengan membuang satu huruf dari bagian yang match dari input string  (yang sudah menjadi bagian match-nya) untuk dipake/di-match oleh character berikutnya pada matcher. Misalnya jika  pattern-nya adalah .*foo ketika string input adalah  xfooasdasfsdfsdafoo maka yang terjadi adalah, bagian pertama dari matcher, yakni .* (yang artinya match semua jenis character dengan jumlah berapa saja, zero or more times), akan nge-match seluruh input string (greedy = rakus/sebanyak mungkin). Karena seluruh string sudah match dengan dia, otomatis bagian berikutnya dari matcher, yakni character f tidak akan mendapat jatah lagi, dan tidak match. Jadi quantifier tadi, yakni *,  akan membuang satu character dari bagian  match-nya sehingga character o  pada input string  menjadi unmatch (di luar dari bagian match-nya), dan ini yang selanjutnya akan di-match dengan character f dari matcher. Namun belum match, dia buang lagi  o berikutnya, dan belum match juga dengan  pada matcher, maka f tadi dibuang lagi dari bagian match dari matcher .* sehingga bisa dipake oleh character f dari matcher, dan ini baru match. Kemudian character berikutnya dari matcher yakni o dan o, dengan sendirinya akan match dengan dua character sebelumnya yang sudah dibuang oleh matcher .* yakni o dan o.

Dalam modus recultant, dia akan nge-match sesedikit mungkin (berkebalikan dengan modus greedy tadi).  Jadi dalam  input yang diberikan, yakni xfooasdasfsdfsdafoo, matcher .*? akan ngematch sesedikit mungkin, yakni  pertama match dengan string dengan zero-length, atau  “” (tanda kutip di sini menunjukkan ada string di situ yang tidak keliatan), sesuai dengan defenisinya (zero or more times). Selanjutnya bagian berikutnya dari matcher, yakni  f,  akan mencoba nge-match dengan mengambil satu-satu dari string yang tersisa, yakni  xfooasdasfsdfsdafoo (di luar string zero-length tadi), di mana pertama-tama dia mencoba nge-match dengan character x. Karena tidak match, maka quantifier *? akan melahap satu lagi dari string input (melakukan backtrack) yakni x, sehingga bagian pertama dari matcher, yakni .*? akan menyisakan fooasdasfsdfsdafoo untuk di match dengan bagian berikutnya dari matcher, yakni f. Karena sudah match,  maka  bagian  berikutnya dari input string yang  tersisa yakni character o dari ooasdasfsdfsdafoo yang akan dimatch dengan bagian berikutnya dari matcher yakni o, demikian pula untuk o berikutnya.

Modus possessive sama sekali tidak melakukan backtracking. Jadi quantifier .*+ akan melahap semua string input, dan sama sekali tidak menyisakan untuk bagian berikutnya dari matcher, yakni f, o, dan o. Sehingga hasil keseluruhannya adalah string input sama sekali tidak match dengan matcher.

Friday, August 15, 2014

Mencari data terduplikasi dengan menggunakan Java HashMap

Dalam tutorial kali ini, saya mencoba mendemonstrasikan kegunaan hashmap di java, yakni dalam mencari tahu apakah suatu data terduplikasi. Contohnya adalah biasa dalam sebuah database berbasis SQL ada perintah distinct yang mana secara kasar bisa dikatakan bahwa perintah ini menggunakan hashmap dalam implementasinya.

Saya berikan contoh, adalah bagaimana mencari dalam suatu file pada baris ke berapa saja kolom ke-x mengalami duplikasi. Sebenarnya ini perluasan dari pertanyaan fundamental yakni, apakah suatu data memiliki jumlah lebih dari satu dalam suatu kumpulan data. Kemudian saya melakukan perluasan dengan memberikan jawaban mengenai di baris mana saja data tersebut mengalami duplikasi. Potongan kodenya dapat dilihat pada script berikut:

Untuk mendemonstrasikan apakah script ini berjalan dengan baik, ada baiknya pembaca membuat sendiri test-case nya. Buat aja beberapa baris yang data pada kolom-kolomnya itu beda, kecuali pada beberapa kolom yang dibuat sama. Kemudian selanjutnya pembaca jalankan aja script ini untuk mengetesnya.

Sunday, January 19, 2014

Mengganti access modifier (tipe variabel: private, protected, final menjadi public) di Java

Berikut ini saya berikan contoh kegunaan Reflection di java. Yakni untuk mengganti tipe access modifier. Misalnya kita mempunyai kelas yang field-nya dibuat private, maka kita dapat menggunakan reflection untuk membuatnya jadi public. Perhatikan contoh berikut

Kita dapat merubah nilai field name yang private sekaligus final dalam kelas tersebut dengan bantuan reflection di Java. Perhatikan contoh berikut

Hasil eksekusinya adalah:

Menggunakan generic untuk conversi list di Java

Salah satu dari kegunaan generic di java adalah untuk mengkonversi list objek tipe tertentu menjadi list objek tipe turunannya.  Jika kita ingin mengkonversi list yang berisi objek tipe A menjadi list objek tipe B (yang mengekstends A), itu tidak bisa dilakukan secara langsung, seperti contoh berikut

Pada contoh di atas method convert tersebut tidak bisa dituliskan seperti itu, walaupun kelas B mengekstends kelas A. Yang harus dilakukan adalah dengan menggunakan generic seperti potongan berikut

Dan itupun hanya berlaku jika kelas B mengekstends kelas A. Jika tidak akan terjadi error misalnya:

Yang akan menghasilkan output

Tuesday, December 3, 2013

Convert List Generic ke list tipe tertentu di java

Berikut ini adalah contoh bagaimana mengconvert list generic ke list tipe tertentu di java

Tuesday, September 17, 2013

Java Parallel fork/join

Dalam Tulisan kali ini saya ingin sedikit berbagi pengalaman tentang hal-hal terbaru yang nanti akan keluar di java 8. Seperti kita ketahui, nanti rencananya akan ada sedikit pembaruan terhadap rilis selanjutnya dari java, antara lain adanya lambda expression, bulk operation, method-reference, dan yang paling keren nanti adalah adanya optimasi parallel-computing dengan bantuan teknik fork/join.

Optimisasi dengan metode fork/join ini mengambil keuntungan dari kemampuan multicore processor. Sehingga multithread tidak dicoding secara manual, akan tetapi tinggal menerapkan implementasinya.  Agar bisa menggunakan konsep fork/join ini, terlebih dahulu anda harus menyediakan jdk8 beserta IDE yang sesuai. Bagi pengguna eclipse petunjuknya bisa dilihat di link berikut:
 http://www.oracle.com/technetwork/articles/java/lambda-1984522.html

Setelah saya mencoba mengimplementasikan teknik ini pada sebuah  percobaan sederhana, yakni simulasi SPH, ternyata terdapat perbedaan yang cukup signifikan antara menggunakan teknik ini dengan tidak menggunakan teknik ini. Dalam simulasi SPH tersebut, partikel yang digunakan sejumlah 2500. Ketika tidak menggunakan teknik fork/join simulasi yang dilakukan agak tersendat-sendat. Hal ini dapat dilihat pada video berikut:



Sementara ketika teknik fork/join digunakan hasil simulasinya menjadi mulus, yang dapat dilihat pada video berikut:



Adapun sedikit potongan kode bagaimana mengimplementasikan konsep ini ke dalam project yang dibuat---disamping sudah dijelaskan pada tutorial di atas---dapat dilihat pada snippet berikut:

Friday, August 23, 2013

Cara sortir di Java

Tanpa perlu basa-basi saya akan memberikan sedikit tutorial yakni bagaimana cara menyortir list di java. Seperti kita ketahui list itu sendiri merupakan suatu kumpulan objek. Untuk keperluan sortir sendiri, java sudah menyediakan fasilitas built-in ke kita. Yakni dengan menggunakan utilitas pada java Collections. Berdasarkan informasi yang saya peroleh, algoritma yang digunakan dalam java sorting ini adalah merge sort [1]. Tanpa perlu berbasa basi saudara tinggal menyalin contoh berikut dan langsung di running di komputer anda.

Jika sudah maka hasil yang akan ditampilkan adalah sebagai berikut:

1. http://www.coderanch.com/t/520171/java/java/Collections-sort-merge-sort-insteadof

Tuesday, August 20, 2013

Animasi Bola Biliard dengan JavaFX

Kali ini saya akan memberikan sebuah tutorial mengenai bagaimana membuat animasi bola billiard dengan javaFX yang preview-nya dapat dilihat pada gambar berikut:

 

Adapun source codenya adalah sebagai berikut:

package fjr.collision;

import java.util.ArrayList;
import java.util.Random;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CircleBuilder;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BilliardBallDetection extends Application {

  ArrayList listParticle;
 ArrayList listCircle; 

 double xwidth = 400;
 double ywidth = 400;

 double timeStep = 2.5;
 double numberParticle = 9;
 Random rand = new Random();

 double dmin = 30.0;

 double xmax = xwidth;
 double xmin = 0.0;
 double ymax = ywidth;
 double ymin = 0.0;
 double size = 0.0;

 double dmax = 0.0;
 
 double vmax = 3.0; 


 Timeline animation; 
 Button buttonPause, buttonPlay; 
 
 @Override
 public void start(Stage primarySrage) throws Exception {
  // TODO Auto-generated method stub
  generateParticle();
  removeOverlap(listParticle);
  generateCircle();
  
  Group root = new Group(); 
  for(int i =0; i< listCircle.size(); i++){
   Circle c = listCircle.get(i); 
   root.getChildren().add(c); 
  }
  
  animation = new Timeline(); 
  animation.setCycleCount(Timeline.INDEFINITE);
  animation.setAutoReverse(false);
  
  KeyFrame kf = new KeyFrame(Duration.millis(20), new EventHandler(){

   @Override
   public void handle(ActionEvent event) {
    // TODO Auto-generated method stub
    checkBoundary();
    calculateCollision();
    moveParticle(); 
    redrawCircle();
   }
   
  }); 

  animation.getKeyFrames().add(kf); 
  
  root.getChildren().addAll(buttonPlay = ButtonBuilder.create()
    .text("PLAY").onAction(new EventHandler() {

     @Override
     public void handle(ActionEvent arg0) {
      // TODO Auto-generated method stub
      animation.play();
     }
    }).translateX(10).translateY(10)
    .build(), 
    buttonPause = ButtonBuilder.create()
    
    .text("PAUSE").translateX(80).translateY(10)
    .onAction(new EventHandler() {

     @Override
     public void handle(ActionEvent arg0) {
      // TODO Auto-generated method stub
      animation.pause();
     }
    })
    .build() 

    ); 
  primarySrage.setScene(new Scene(root, xwidth, ywidth));
  primarySrage.show();
 }
 
 private void redrawCircle(){
  for(int i=0; i< listCircle.size(); i++){
   Circle c = listCircle.get(i); 
   Particle  p  = listParticle.get(i); 
   c.setCenterX(p.x);
   c.setCenterY(p.y);
  }
 }
 
 
 private void generateCircle(){
  listCircle = new ArrayList<>(); 
  for(int i=0; i< listParticle.size(); i++){
   Particle p = listParticle.get(i); 
   Circle c = CircleBuilder.create()
     .centerX(p.x).centerY(p.y).radius(dmin)
     .build(); 
   listCircle.add(c);
  }
 }

 private void generateParticle() {
  listParticle = new ArrayList<>();
  for (int i = 0; i < numberParticle; i++) {
   Particle particle = new Particle(rand.nextDouble() * xwidth,
     rand.nextDouble() * ywidth, rand.nextDouble() * vmax,
     rand.nextDouble() * vmax);
   listParticle.add(particle);
  }
 }


 private void calculateCollision(){
  for(int i=0; i< listParticle.size(); i++){
   Particle p1  = listParticle.get(i); 
   for(int j= i+1; j< listParticle.size(); j++ ){
    Particle p2 = listParticle.get(j); 
    chekCollision(p1, p2);
   }
  }
 }
 
 public void chekCollision(Particle p1, Particle p2) {
  
  if (isOverlap(p1, p2)) {
   
   double deltaX = p1.x - p2.x;
   double deltaY = p1.y - p2.y;
   double distance =  Math.sqrt(deltaX * deltaX + deltaY * deltaY);
   deltaX = deltaX/ distance;
   deltaY = deltaY/distance; 
   
   double aci = p1.vx * deltaX + p1.vy * deltaY; 
   double bci = p2.vx * deltaX + p2.vy * deltaY; 
   
   double acf = bci; 
   double bcf = aci; 
   
   p1.vx = p1.vx + (acf - aci) * deltaX; 
   p1.vy = p1.vy + (acf - aci) * deltaY; 
   p2.vx = p2.vx + (bcf - bci) * deltaX; 
   p2.vy = p2.vy + (bcf - bci) * deltaY;
  }
 }

 private void moveParticle() {
  for (int i = 0; i < listParticle.size(); i++) {
   Particle p = listParticle.get(i);
   p.x += p.vx * timeStep;
   p.y += p.vy * timeStep;
  }
 }


 public void removeOverlap(ArrayList list) {
  for (int i = 0; i < list.size(); i++) {
   Particle p1 = list.get(i);
   for (int j = list.size() - 1; j > i; j--) {
    Particle p2 = list.get(j);
    if(isOverlap(p1, p2))
     list.remove(j); 
   }
  }
 }
 
 public void checkBoundary(){
  for(int i =0; i< listParticle.size() ;i++){
   Particle p = listParticle.get(i); 
   if(p.x > xmax - dmin)
    p.vx = -Math.abs(p.vx) ;
   if(p.x < xmin + dmin)
    p.vx = Math.abs(p.vx); 
   if(p.y > ymax - dmin)
    p.vy = - Math.abs(p.vy);
   if(p.y < ymin + dmin)
    p.vy = Math.abs(p.vy); 
  }
 }
 
 private boolean isOverlap(Particle p1, Particle p2){
  double deltax = p1.x - p2.x; 
  double deltay = p1.y - p2.y; 
  if(deltax * deltax + deltay * deltay < 4 * dmin * dmin)
   return true; 
  return false; 
 }
 
 public static void main(String[] args) {
  launch(args);
 }

 private class Particle {
  double x = 0.0;
  double y = 0.0;
  double vx = 0.0;
  double vy = 0.0;
  public Particle(double x, double y , double vx , double vy ) {
   this.x = x;
   this.y = y;
   this.vx  = vx ;
   this.vy = vy; 
  }
 }
}

Thursday, June 6, 2013

Kriptografi satu arah

package fjr.lain;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Random;

public class Criptografi1 
{
 // ini adalah program kriptografi sederhana yang tidak mungkin bisa di decode kembali
 // kecuali jika anda bisa memahami benar pseudo random generator di java
 // istilahnya (pseudo) one-way cryptic
 static StringBuilder result ; 
 public static String getResult(String input){
  result = new StringBuilder(); 
  String[] split = input.split("\\s");
  Random rand = new Random(); 
  for(int i=0; i< split.length; i++){
   char[] temp = split[i].toCharArray();
   if(!(rand.nextInt(2) == 0)){ //biar masih kebaca
    for(int j = 0; j< temp.length; j++){
     int c = rand.nextInt(temp.length);
     char cc = temp[j]; 
     temp[j] = temp[c];
     temp[c] = cc; 
    }
   
   }
   result .append(String.copyValueOf(temp)).append(" ");
  }
  return result.toString().toLowerCase();
 }

 public static void main(String[]args){
  BufferedReader br = null; 
  try{
   br = new BufferedReader(new FileReader(new File("D:/source.txt")));
   String res = "";
   while((res = br.readLine())!= null){
    System.out.println(Criptografi1.getResult(res));
   }
  }catch(Exception e){
  }
 }
}
paad tulisan ini saya kana memberikan esbuha siiup untukmu eanosgr ho wahai skikaeh punaja aith aku kat uath apakah iin ubgsa abig tanesehka nautnjkgu yang jelas tiap lmmaa kua sangat rnidkmumneua aku ahner mengapa uka ibtuge taeg membiarkanku epabrhar aaudmp kau selalu mbripemi gabminaaa asnyaar ibas uesbebruht denganmu uka selalu berharap suatu tsaa aku jadi janda kau kana kuangkat jadi seorang ibu negara jkai aku nanti jadi presiden

tapi memang perasaan hati tak bisa aaiwdln aegmnpa nrtaauougm begitu tega memisahkan kita berdua apahka kau benar-benar autis taau gimana agyn lasej kau traeilht astgan nmasi saat kita ernbdhpaaa apakah semua nroga hanya mencoba iymanenkuaetmg aku ujag atk tauh yang sjeal aku sudah ealltru nciat aku akt bisa dilawan lagi untuk laules berbunga-bunga akietk mengenangmu hwaia uaapjn htia kua akan lsuela menunggu dan terus menunggu sampai suatu saat tiann auk anka idajmne adnja

Saturday, December 15, 2012

Belajar plot berjalan di java

Dalam tulisan kali ini saya akan memberikan contoh source code java yang bisa digunakan dalam membuat plotting berjalan seperti yang dimaksud pada situs http://www.chem.mtu.edu/~tbco/cm416/newpida.html
(pastikan di komputer anda terinstal java untuk melihat simulasi yang dimaksud)
Untuk mencoba secara sederhana bagaimana algoritma yang digunakan dalam program tersebut, anda dapat mencoba source code berikut:

Saturday, December 8, 2012

Hypocycloid di java

Berikut saya berikan contoh bagaimana membuat animasi hypocycloid di java:

source code nya:
  /**
   * Copyright 2012, Moh. Fajar
   * 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see 
    */


package fjr.geometri;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 *
 * @author mamat
 */
public class Hypocycloid extends JPanel {

    //posisi dan ukuran persegi utama
    int rectX = 10;
    int rectY = 10;
    int rectH = 420;
    int rectW = 600;
    
    //posisi dan diameter lingkaran  besar
    int radius1 = 270;
//    int x = rectW+rectX-radius1;
    int x = rectX;
    int y = rectH+rectY - radius1;
   
    //posisi dan diameter lingkaran kecil
    int radius2 = 100;
    int x1 = x + (radius1 - radius2) / 2, 
            y1 = y + (radius1 - radius2);
    
    //sudut putaran lingkaran kecil
    double omega = 0; 
    
    //posisi dan titik Hypocycloid
    int x2= x1+radius2;
    int y2 = x1 + radius2;
   
    public Hypocycloid() {
        this.start();
    }

    @Override
    public void paint(Graphics g) {
        super.paintComponent(g);
        drawMainRect(g);
        drawBigCircle(g);
        drawSmallCircle(g);
        drawPoint(g);
    }
   
    public void drawBigCircle(Graphics g) {
        g.setColor(Color.red);
        g.drawOval(x, y, radius1, radius1);
    }
    
    public void drawSmallCircle(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawOval(x1, y1, radius2, radius2);

    }

    public void drawMainRect(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawRect(rectX, rectY, rectW, rectH);
    }
    
    public void drawPoint(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        g2.setColor(Color.black);
        g2.fillOval(x2, y2, 10, 10);
        
    }
  
    public void start() {
        LingkaranDalam lingkarandalam = new LingkaranDalam(this);
        Thread t1 = new Thread(lingkarandalam);
        t1.start();
        LingkaranLuar lingkarangluar = new LingkaranLuar(this);
        Thread t2 = new Thread(lingkarangluar);
        t2.start();
              
    }
    
    private class LingkaranLuar implements Runnable {
        
        Hypocycloid hypo;
        
        public LingkaranLuar(Hypocycloid hypo){
            this.hypo = hypo;
        }
        
        @Override
        public void run() {

            while (true) {
                for (int i = 0; i < 110; i++) {//sorong ke kiri
                    x += (int) ((rectW + rectX - radius1) / 100);
                    synchronized (hypo) {
                        hypo.repaint();
                    }
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                        System.out.println("thread error 2");
                    }
                }

                for (int i = 0; i < 50; i++) { //sorong ke atas
                    y -= (int) ((rectH + rectY - radius1) / 50);
                    synchronized (hypo) {
                        hypo.repaint();
                    }
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                        System.out.println("thread error 2");
                    }
                }

                for (int i = 0; i <110; i++) { //sorong ke kanan
                    x -= (int) ((rectW + rectX - radius1) / 100);
                    synchronized (hypo) {
                        hypo.repaint();
                    }
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                        System.out.println("thread error 2");
                    }
                }

                for (int i = 0; i < 50; i++) { //sorong ke bawah
                    y += (int) ((rectH + rectY - radius1) / 50);
                    synchronized (hypo) {
                        hypo.repaint();
                    }
                    try {
                        Thread.sleep(20);
                    } catch (Exception e) {
                        System.out.println("thread error 2");
                    }
                }
            }

        }
    }

    private class LingkaranDalam implements Runnable {
        
        Hypocycloid hypo;
        
        public LingkaranDalam(Hypocycloid hypo){
            this.hypo = hypo;
        }

        @Override
        public void run() {
            boolean run = true;
            int a = radius1/2;
            int b = radius2/2;
            int rtemp = a - b;
            while (run) {
                for (int i = 0; i < 200; i++) {
                    omega -= Math.PI / 200;
                    x1 = (int) (x + rtemp + rtemp * Math.cos(omega));
                    y1 = (int) (y + rtemp + rtemp * Math.sin(omega));
                       
                    x2 = (int)(x1+(b-5)+b*Math.cos((a-b)*omega/b));
                    y2 = (int)(y1+(b-5)-b*Math.sin((a-b)*omega/b) );
                    
                    synchronized(hypo){
                        hypo.repaint();
                    }
                    try {
                        Thread.sleep(5);
                    } catch (Exception e) {
                        System.out.println("thread error 1");
                    }
                }

            }
        }
    }

    public static void main(String[] args) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame mainframe = new JFrame("Geometri Fun");
                mainframe.setLayout(new BorderLayout());
                mainframe.setPreferredSize(new Dimension(700, 500));
                Hypocycloid hypo = new Hypocycloid();
                mainframe.add(hypo);
                mainframe.setResizable(false);
                mainframe.pack();
                mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                mainframe.setVisible(true);
            }
        });
    }
}

Saturday, June 30, 2012

Penggunaan itext

Kali ini saya akan membagi pengalaman saya  bagaimana caranya menggunakan  itext pdf library. Itext merupakana library dalam bahasa java yang bisa digunakan untuk membuat dan memanipulasi file pdf. Bagi yang belum pernah mendengar dan ingin mencobanya, silakan didownload di http://itextpdf.com/ .

Sebenarnya  saya menemukan sebuah masalah kecil, yakni bagaimana me-rename  file-file jurnal dalam bentuk  pdf yang barusan saya download di web Elsevier. Kebetulan file-file nya hanya dinamakan sesuai bagian jurnalnya, sementara yang saya inginkan adalah bagaimana  agar file tadi diberi nama sesuai dengan judul karya tulis  tersebut oleh penyusunnya. Me-rename nya dengan membuka satu-persatu filenya untuk melihat judulnya  tentunya sangat membosankan.  Agar lebih jelas, perhatikan  gambar berikut:


Setelah bergulat dengan waktu, akhirnya saya bisa membuat program sederhana untuk maksud tersebut. Sehingga file-file nya bisa di-rename sesuai dengan judulnya. Kendatipun demikian, masih ada sebagian  yang belum berhasil di rename dan sampai saat ini saya masih mencari tahu dimana masalahnya. Adapun hasil rename-nya adalah sebagai berikut:




Source code nya: