Tuesday, June 20, 2017

Aggregate class - Tutorial






public class SentenceDemo{
   public static void main(String[] args){
      
       Sentence s1=new Sentence();
       System.out.println(s1.getMessage());
       System.out.println(s1.getMessage());
       System.out.println(s1.getMessage());
       System.out.println(s1.getMessage());
       System.out.println(s1.getMessage());
       System.out.println(s1.getMessage());
       System.out.println(s1.getCounter());
    }
}

public class Sentence{
  private String message;
  public static final int SIZE=5;
  private static int counter;
  private String messages[]={
      new Pronoun().getWord()+new Verb().getWord()+new Adjective().getWord()+new Adverb().getWord(),
      new Pronoun().getWord()+new Verb().getWord()+new Adjective().getWord()+new Adverb().getWord(),
      new Pronoun().getWord()+new Verb().getWord()+new Adjective().getWord()+new Adverb().getWord(),
      new Pronoun().getWord()+new Verb().getWord()+new Adjective().getWord()+new Adverb().getWord(),
      new Pronoun().getWord()+new Verb().getWord()+new Adjective().getWord()+new Adverb().getWord(),
    };
  public Sentence(){
      java.util.Random ran=new java.util.Random();
      message=messages[ran.nextInt(SIZE)]+".";
     counter++;
    }
  private Sentence(String message){
      super();
      this.message=message;
      counter++;
    }
  public String getMessage(){
      java.util.Random ran=new java.util.Random();
      message=messages[ran.nextInt(SIZE)]+".";
      message=message.replaceFirst("[a-zA-Z]", ""+Character.toUpperCase(message.charAt(0)));
      return message;
    }
    public Sentence deepCopy(Sentence s){
        return new Sentence(s.message);
    }
    public boolean equals(Sentence s){
        return (message.equals(s.message))?true:false;
    }
    public int getCounter(){
        return counter;
    }
}

public class Verb{
  private String word;
  private String words[]={" write "," run "," drive "," walk ","crawl"};
  public Verb(){
      java.util.Random ran=new java.util.Random();
      word=words[ran.nextInt(Sentence.SIZE)];
    }
  public String getWord(){
      return word;
    }
}

public class Pronoun{
  private String word;
  private String words[]={"I ","you ","me ","we ","us "};
  public Pronoun(){
      java.util.Random ran=new java.util.Random();
      word=words[ran.nextInt(Sentence.SIZE)];
    }
  public String getWord(){
      return word;
    }
}

public class Adjective{
  private String word;
  private String words[]={" very "," quiet ","  "," short "," creepy "};
  public Adjective(){
      java.util.Random ran=new java.util.Random();
      word=words[ran.nextInt(Sentence.SIZE)];
    }
  public String getWord(){
      return word;
    }
}

public class Adverb{
  private String word;
  private String words[]={" quickly "," very "," slowly "," beautifully "," happily "};
  public Adverb(){
      java.util.Random ran=new java.util.Random();
      word=words[ran.nextInt(Sentence.SIZE)];
    }
  public String getWord(){
      return word;
    }
}

Sunday, June 18, 2017

Copy Command - Java Tutorial

The entire process from preparation to structured design and from procedural programming to object oriented programming.

The missing tutorial that will show you not just what and how, but the most crucial steps of why.

Watch the video here - https://youtu.be/JM5MZxKKMgM

Plan:
Know a simple copy command from the command line and think about the process of copying a file content.  Think about the characteristics of a file and what aspects of those characteristics can be used in order to perform and to control the copy process.
Type copy /? on your terminal to read its help file and copy simple files, but make sure to make mistakes like wrong input file or wrong path to see how the utility handles those mistakes.

You can always display the return value by typing echo %errorlevel% to learn about how the programmers decided to handle error conditions.  In our case, we'll return 2017 if the input file does not exists and 2018 if the output file already exists, since we do not want to overwrite it.


Design: UML+Structured logic ( DIA )
Code: (BlueJ )

import java.io.File;
import java.util.Scanner;
import java.io.FileWriter;
import java.io.PrintWriter;

/**
 * <h1>Copies a text file to another</h1>
 * @author Zoltan Szabo
 * @version 1.0.0
 */

public class Copy{
   private String from;
   private String to;
   /**
    * Initializes the source and destination file names
    * @param source Name of the input file
    * @param destination Name of the output file
    */

   public Copy(String source, String destination){
       from= source;
       to=destination;
    }
   
/**
 * Performs the actual file copy
 * @throws IOException if the input file does not exists
 */

public void copy()throws java.io.IOException{
   //Creates a new File instance by converting the given pathname string into an abstract pathname.
   File input=new File(from);
   File output=new File(to);
    
      //Tests whether the file or directory denoted by this abstract pathname exists.
   if(!input.exists()){
       //getName()-Returns the name of the file or directory denoted by this abstract pathname.
       System.out.println("Input file "+input.getName()+" does not exists or path is wrong!");
       //Terminates the currently running Java Virtual Machine.
       System.exit(2017);
      
    }
  
          //Tests whether the file or directory denoted by this abstract pathname exists.
   if(output.exists()){
       //getName()-Returns the name of the file or directory denoted by this abstract pathname.
       System.out.println("Output file "+output.getName()+" already exists!");
       //Terminates the currently running Java Virtual Machine.
       System.exit(2018);
      
    }
   
   //Constructs a new Scanner that produces values scanned from the specified file.
   Scanner inputFile=new Scanner(input);
   //FileWriter out=new FileWriter(output,true);
   PrintWriter outputFile=new PrintWriter(output);
  
   //Loop through the inputFile and write to outputFile - the actual work of the application
   //hasNext() - Returns true if this scanner has another token in its input.

   while(inputFile.hasNext()){
       //println - Prints a String and then terminates the line.
       //nextLine - Advances this scanner past the current line and returns the input that was skipped.

       outputFile.println(inputFile.nextLine());
    }
  
   //Closes the stream and releases any system resources associated with it.
   inputFile.close();
   outputFile.close();
}
}



/**
 *<h1> Application to copy a text file into another</h1>
 *
 * @author Zoltan Szabo
 * @version 1.0.0
 */

public class MyCopy{
    /**
     * Entry point to the application
     * @param args String array from the command line
     * @throws IOException if the input file does not exists
     */

    public static void main(String args[]) throws java.io.IOException{
       Copy myCopy=new Copy(args[0], args[1]);
       myCopy.copy();
}
}

Sunday, May 14, 2017

What is Program Design by Example - ISBN-10

Writing a program by an engineer starts, just like creating the blueprint of a building by an architect, by design.  Before we get to the design phase, we have to understand and then analyze the problem.

Problem:  Given a book title and its ISBN-10 number, you need to validate if the ISBN number is valid or not.
Starting Out with Java: Early Objects (5th Edition) 5th Edition
ISBN-10: 0133776743

Analysis:  ISBN-10 is a unique number that must be generated based on an algorithm that must ensure its unique value and its validity must be verifiable.  Let's find out how the algorithm works and if there is a reliable source that we can refer to.
I can see that it does have a check digit at the end of the number:
https://www.isbn-international.org/content/standard-book-numbering-turns-50
I can see how it is calculated in ISBN-13, but not in ISBN-10
https://www.isbn-international.org/sites/default/files/ISBN%20Manual%202012%20-corr.pdf
I got it, this looks reliable source
https://www.isbn-information.com/the-10-digit-isbn.html
Let's work out the example in the document to see if I understand it.
Now, let's use the given ISBN and do the calculation by hand on paper so I'll understand how it is done, before I decide on how to write a program.
So, the number is 0133776743
Let's multiply 0*10+1*9+3*8+3*7+7*6+7*5+6*4+7*3+4*2 = 184
184 mod 11 = 8
Thus, 11-8=3 is the correct remainder, so it must be correct.

Design:
start
    input number
    while number length is not 10             //validate length
           input number
    endwhile
    set index=0
    while index < 9 then                           //skip the last digit
           if number[index] is digit then
               total=total+number[index]*(10-index)         //accumulator
           else
                output "Not a digit, bye"                 //validate each digit
                exit program with code 1
           index=index+1
   endwhile
   total=total mod 11
   if total eq 10 then               //show 0 for remainder 10     
       output "The check digit is: "+0
   else
       output "The check digit is: "+11-total
   endif
stop


Code:
import java.util.Scanner;




/** Application to calculate ISBN-10 check digit
 @author Zoltan Szabo
 @version 1.0.0
*/
public class MyISBN10{
public static void main(String args[]){
    Scanner kbd=new Scanner(System.in);
    String isbn;
    int total=0;
    System.out.print("Please, enter an ISBN-10 number: ");
    isbn=kbd.nextLine();
    while(isbn.length()!=10){  //validate input length
        System.out.println("This application can only handle ISBN-10, do not type more than 10 digits.");
        System.out.print("Again: Please, enter an ISBN-10 number: ");
        isbn=kbd.nextLine();
    }
    for(int index=0;index<9;index++){   //process one digit at a time
        if(Character.isDigit(isbn.charAt(index)))  //validate if number was read
           total+=Integer.parseInt(isbn.substring(index,index+1))*(10-index);
         else{
            System.out.print("Not a digit, bye!");
            System.exit(1);
            }
    }
    System.out.print("The check digit is: "+(((total%11)==10)?0:11-(total%11)));
}
}

Test: ( not just valid, but also invalid inputs )

Please, enter an ISBN-10 number: 0133776743
The check digit is: 3
Please, enter an ISBN-10 number: as0133776743
This application can only handle ISBN-10, do not type more than 10 digits.
Again: Please, enter an ISBN-10 number: 01337767aa
Not a digit, bye!

Challenge:  Do the same for ISBN-13

Saturday, May 13, 2017

Don't Even Think about a Job Interview without Knowing these Sort Algorithms

Sorting is an essential part of working with data today.  Data access and analysis is much less time consuming if the data itself is sorted first.  Unsorted data is very silent while sorted data can be questioned and fast response is possible.  If you want to find the smallest and largest values from an unsorted data, it might take a very long time ( It might be as bad as O(n^2) ), but asking the same question from a sorted data can be as quick as O(1) since you just have to take the first and last element of the sorted structure.  Yes, it takes time and work to sort the data, but that extra work ahead of time, before the question is asked, is more than worth the effort.  Sorting can be accomplished in many different way with different time complexities.



·        Bubble sort
·        Selection sort
·        Insertion sort
·        Merge sort
·        Quick sort

Performance tests must be performed and studied in order to chose the correct one when the time comes.  It is not the time to test when the job needs to be done.

99
N Time:                                   00:00:00:0002
99
N-quare Time:                         00:00:20:20446
99
BubbleSort based Time:          00:00:26:26496
99
SelectionSort based Time:      00:00:04:4924
99
InsertionSort based Time:       00:00:02:2467
99
MergeSort based Time:          00:00:00:0014
99
QuickSort based Time:          00:00:00:0008

Aiming for your dream job will require you to understand the methodology, code, and operational characteristics or these algorithms.  So, spend lots of time analyzing and studying these algorithms and run the code for performance analysis.  This will be one of your greatest assets and skills that will get you your dream job and will allow you to keep your dream job for a long time.

public class BiggestDifference {
    public static void main(String[] args){

        final int SIZE=10000;
        int myArray[]= new int[SIZE];
        initialize(myArray);
        long time=System.currentTimeMillis();
        System.out.println(diffItN(myArray));
        System.out.printf("N Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        time=System.currentTimeMillis();
        System.out.println(diffItNN(myArray));
        System.out.printf("N-quare Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        time=System.currentTimeMillis();
        System.out.println(diffItNLogN(myArray,"bubble"));
        System.out.printf("BubbleSort based Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        initialize(myArray);
        time=System.currentTimeMillis();
        System.out.println(diffItNLogN(myArray,"selection"));
        System.out.printf("SelectionSort based Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        initialize(myArray);
        time=System.currentTimeMillis();
        System.out.println(diffItNLogN(myArray,"insertion"));
        System.out.printf("InsertionSort based Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        initialize(myArray);
        time=System.currentTimeMillis();
        System.out.println(diffItNLogN(myArray,"merge"));
        System.out.printf("MergeSort based Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        initialize(myArray);
        time=System.currentTimeMillis();
        System.out.println(diffItNLogN(myArray,"quick"));
        System.out.printf("QuickSort based Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
    }

    private static void initialize(int a[]){       
        java.util.Random ran=new java.util.Random();
        for(int i=0;i<a.length;i++){
            a[i]=ran.nextInt(100);
        }
    }

    private static int diffItN(int a[]){
        int largest=a[0];
        int smallest=a[0];
        for(int i=1;i<a.length;i++){
            if(a[i]>largest)
                largest=a[i];
            if(a[i]<smallest)
                smallest=a[i];
        }
        return largest-smallest;
    }

    private static int diffItNN(int a[]){
        int difference = 0,diff=0;
        for(int n1:a){
            for (int n2:a){
                difference = n1 - n2;
                if(difference > diff)
                    diff = difference;
            }
        }
        return diff;
    }

    private static int diffItNLogN(int a[],String s){
        switch(s){
            case "bubble":
                bubbleSort(a);
                break;
            case "selection":
                selectionSort(a);
                break;
            case "insertion":
                insertionSort(a);
                break;
            case "merge":
                mergeSort(a);
                break;
            case "quick":
                quickSort(a,0,a.length-1);
                break;
        }
        return (a[0]>a[a.length-1])?a[0]-a[a.length-1]:a[a.length-1]-a[0];
    }

    private static void bubbleSort( int [ ] num ) {
        int j;
        boolean flag = true;  
        int temp; 
        while ( flag ){
            flag= false;   
            for( j=0;  j < num.length -1;  j++ ) {
                if ( num[ j ] < num[j+1] )   {
                    temp = num[ j ];               
                    num[ j ] = num[ j+1 ];
                    num[ j+1 ] = temp;
                    flag = true;             
                }
            }
        }
    }

    private static void selectionSort ( int []num ){
        int i, j, first, temp; 
        for ( i = num.length - 1; i > 0; i-- ) {
            first = 0;  
            for(j = 1; j <= i; j ++){
                if( num[ j ] < num[ first ] )        
                    first = j;
            }
            temp = num[ first ];  
            num[ first ] = num[ i ];
            num[ i ] = temp;
        }          
    }

    private static void insertionSort(int array[]) { 
        int n = array.length; 
        for (int j = 1; j < n; j++) { 
            int key = array[j]; 
            int i = j-1; 
            while ( (i > -1) && ( array [i] > key ) ) { 
                array [i+1] = array [i]; 
                i--; 
            } 
            array[i+1] = key; 
        } 
        System.out.println();
    } 

    private static void mergeSort(int [ ] a){
        int[] tmp = new int[a.length];
        mergeSort(a, tmp,  0,  a.length - 1);
    }

    private static void mergeSort(int [ ] a, int [ ] tmp, int left, int right){
        if( left < right ){
            int center = (left + right) / 2;
            mergeSort(a, tmp, left, center);
            mergeSort(a, tmp, center + 1, right);
            merge(a, tmp, left, center + 1, right);
        }
    }

    private static void merge(int[ ] a, int[ ] tmp, int left, int right, int rightEnd ){
        int leftEnd = right - 1;
        int k = left;
        int num = rightEnd - left + 1;

        while(left <= leftEnd && right <= rightEnd)
            if(a[left]<a[right])
                tmp[k++] = a[left++];
            else
                tmp[k++] = a[right++];

        while(left <= leftEnd)  
            tmp[k++] = a[left++];

        while(right <= rightEnd)
            tmp[k++] = a[right++];

        for(int i = 0; i < num; i++, rightEnd--)
            a[rightEnd] = tmp[rightEnd];
    }

    private static void quickSort(int a[], int lowerIndex, int higherIndex) {
        int i = lowerIndex;
        int j = higherIndex;
        int pivot = a[lowerIndex+(higherIndex-lowerIndex)/2];
        while (i <= j) {
            while (a[i] < pivot) {
                i++;
            }
            while (a[j] > pivot) {
                j--;
            }
            if (i <= j) {
                exchangeNumbers(a,i, j);
                i++;
                j--;
            }
        }
        if (lowerIndex < j)
            quickSort(a,lowerIndex, j);
        if (i < higherIndex)
            quickSort(a,i, higherIndex);
    }

    private static void exchangeNumbers(int a[],int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    private static String getTime(long millis){
        long second = (millis / 1000) % 60;
        long minute = (millis / (1000 * 60)) % 60;
        long hour = (millis / (1000 * 60 * 60)) % 24;
        return String.format("%02d:%02d:%02d:%04d", hour, minute, second, millis);
    }
}

Monday, May 8, 2017

BigInteger - Size Matters

As numbers get larger, you need to consider storing those values where a 64 bit data type is not enough.  Working with large numbers are fun even if the operators do not work as excepted with small numbers.

Java provides classes like java.math.BigInteger or java.math.BigDecimal to handle large numbers, but it takes some time getting used to.  

You don't just add values by using the plus operator ( + ) , you call methods like add(), multiply(), divide(), subtract() methods.

Comparing values are also a challenge.  You really need to read the API in order to know what to expect. 

compareTo() method documentation - "Compares this BigInteger with the specified BigInteger. This method is provided in preference to individual methods for each of the six boolean comparison operators (<, ==, >, >=, !=, <=). The suggested idiom for performing these comparisons is: (x.compareTo(y) <op> 0), where <op> is one of the six comparison operators."

The code below demonstrates the for loop operations using BigInteger.


public class LargeNumbers{
    public static void main(String args[]){
        final java.math.BigInteger NUM=new java.math.BigInteger("10000000");
        //final java.math.BigInteger NUM=new java.math.BigInteger("100000000");
        //final java.math.BigInteger NUM=new java.math.BigInteger("1000000000");
        //System.out.println(NUM.bitCount());  //check to see how many bits are used in the number
        long time=System.currentTimeMillis();
        System.out.println(calc(NUM));
        System.out.printf("Time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
    }

    //iterative recursion
    public static java.math.BigInteger calc(java.math.BigInteger n) {
        java.math.BigInteger result =new java.math.BigInteger("1");
        for (java.math.BigInteger t=n; t.compareTo(new java.math.BigInteger("1")) != 0; t=t.subtract(new java.math.BigInteger("1")))
             result = result.add(t);

        return result;
    }

    private static String getTime(long millis){
        long second = (millis / 1000) % 60;
        long minute = (millis / (1000 * 60)) % 60;
        long hour = (millis / (1000 * 60 * 60)) % 24;
        return String.format("%02d:%02d:%02d:%04d", hour, minute, second, millis);
    }

}

Sunday, May 7, 2017

Head or Tail, Who the Factorial Cares?

Based on the blog post http://www.drdobbs.com/jvm/tail-call-optimization-and-java/240167044
the obvious question came up to see if the performance really noticeable and worth worrying about.  It seems that Oracle does not really concerned about the issue.  In this case, it is not the speed of the algorithm that is an issue, but the limited size of the stack that needs to be used in an optimized manner in order to avoid stack overflow condition.  Based on the code below, my tests show head recursion performs a little bit better than the suggested tail recursion ( when the StarkOverflowError is thrown ).  Over all, it seems like the glory goes to iterative recursion method and not head or tail argument. 

Note: I know that factorial is not what this code is testing, multiplication rises much too fast, so it was replaced, on purpose, by addition operations.


public class TestUtilization{
    public static void main(String args[]){
        final long NUM=5350;    //tailFactorial becomes unstable around 5250-5300, headFactorial 5300-5350
        long time=System.currentTimeMillis();
        System.out.println(IterativeFactorial(NUM));
        System.out.printf("Iterative implementation  time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
        time=System.currentTimeMillis();
        System.out.println(headFactorial(NUM));
        System.out.printf("Head Factorial  time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));  
        /*time=System.currentTimeMillis();
        System.out.println(tailFactorial(NUM));
        System.out.printf("Tail Call Optimization time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));
         */ 
    }
    //Tail Call Optimization
    public static long tailFactorial (long x){
        if (x == 0)
            return 1;
        return tailFactorial(x,1);
    }
    public static long tailFactorial (long x, long current_factorial){
        if (x == 0)
            return current_factorial;
        return tailFactorial(x - 1, current_factorial + x);
    }
    //head recursion
    public static long headFactorial (long x){
        if (x == 0)
            return 1;
        return x+headFactorial(x-1);
    }
    //iterative implementation
    public static long IterativeFactorial(long n) {
        long result = 1;
        for (long t=n; t > 1; t--)
            result += t;
        return result;
    }
    private static String getTime(long millis){
        long second = (millis / 1000) % 60;
        long minute = (millis / (1000 * 60)) % 60;
        long hour = (millis / (1000 * 60 * 60)) % 24;
        return String.format("%02d:%02d:%02d:%04d", hour, minute, second, millis);
    }
}

Friday, May 5, 2017

ArrayList Processing Performance Test

There are many ways to skin a cat, but only six ways to process an ArrayList.  Thus, let's test the performance of each method.  Run it on your system and let us know about your results. Please, give a basic system info if you post.  Thanks!

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;


public class ArrayListSpeedTest {

    public static void main(String[] args) {
        long time=System.currentTimeMillis();
        ArrayList<String> colors=new ArrayList<>();

        for(int i=0;i<100000;i++){  //create a bunch of items for the list, change the value if needed
            colors.add("Red"+i);
        }

        System.out.printf("Initializing ArrayList time: %20s\n\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        for(int i=0;i<colors.size();i++);
        //System.out.println(colors.get(i)+" ");
        System.out.printf("Simple for loop: %32s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        for(String color:colors);
        //System.out.println(color+" ");
        System.out.printf("Enhanced for loop time: %25s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        int i=0;
        while(i++<colors.size());
           //System.out.println(colors.get(i++)+" ");
        System.out.printf("While loop time: %32s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        //Iterator - hasNext, next, remove
        Iterator<String> iterator = colors.iterator();
        while(iterator.hasNext())iterator.next();
             //System.out.println(iterator.next()+" ");
        System.out.printf("While loop Iterator time: %23s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        //ListIterator - hasNext, next, remove, hasPrevious, previous, add
        ListIterator<String> lIterator = colors.listIterator();
        while(lIterator.hasNext())lIterator.next();
             //System.out.println(lIterator.next()+" ");
        System.out.printf("While loop ListIterator time: %19s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
        //Java 8 Stream
        colors.forEach((color)->{});
               //System.out.println(color+" ");});
        System.out.printf("ForEach Stream time: %28s\n",(getTime(System.currentTimeMillis()-time)));   
        time=System.currentTimeMillis();
       
        String name="\n6 Ways to process an ArrayList and speed performance test by Zoltan Szabo";
        name.toUpperCase().chars().forEach(s->{
            System.out.print((char)s);
        });
    }
   
    private static String getTime(long millis){
        long second = (millis / 1000) % 60;
        long minute = (millis / (1000 * 60)) % 60;
        long hour = (millis / (1000 * 60 * 60)) % 24;
        return String.format("%02d:%02d:%02d:%04d", hour, minute, second, millis);
}
}