Tuesday, April 28, 2020

Java docstring Override


 Base class that defines the method getArea that will be overriden by its child class.  This post will explore the annotation that should be used when overriding methods.

@Override is an annotation ( note the capital O )

Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Annotations have a number of uses, among them:
  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — Some annotations are available to be examined at runtime.
ref: https://docs.oracle.com/javase/tutorial/java/annotations/index.html 

Let's create a simple example that you can compile, run, and experiment with to learn the usage of the @Override annotation.

Like with any code, you should start by creating a UML ( in this case, a simplified UML).


/**
 * The Rectangle class stores and manipulates
 * data for a rectangle.
 */


public class Rectangle{
     protected double length;
     protected double width;

    /**
     * Overloaded constructor
     * @param len sets the length field
     * @param w sets the width field
     */

     public Rectangle(double len, double w){
          length = len;
          width = w;
     }

    /**
     * The getArea method returns the value of the
         * length field times the width field.
         * @return the are of the rectangle
     */

     public double getArea() {
          return length * width;
     }
}

And the derived class will be the Box class that will override the getArea method.

/**
 * Extends the Rectangle class to demonstrate the @Override annotation
 */

public class Box extends Rectangle
{
 private double height;
  
 /**
  * Parameterized Constructor
  * @param length
  * @param width
  * @param height
  */

 public Box(double length, double width, double height){
     super(length, width);
     this.height=height;
    }
  

 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

 @Override
  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }
}

The driver is a simple class

  /**
   * Application to calculate the paint needed to paint a house.
   */

public class HousePaintDemo {

public static void main(String args[]){

Box myHouse=new Box(8,10,9);//in feet

System.out.println("You house will need "+myHouse.getArea()+"sqft of paint.");
System.out.printf("One gallon can of paint will cover up to 400 square feet, so you will need %4.0f gallons of paint.\n",Math.ceil(myHouse.getArea()/400*1.1));
}
}

So, why do need the @Override annotation? The answer is simple, you need to look at the documentation and modify the parent method with or without the @Override annotation to see the answer.

Remove the @Override annotation in front of the getArea method in the Box class.  Generate the documentation and read the resulting html page.

  • Method Detail

    • getArea

      public double getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
You can see the documentation is not very helpful since it is not the documentation we wrote for the overriden method. The result is the same if you do not use the annotation properly when it comes to docstrings.

Wrong usage

 @Override
 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }

The annotation must be just before the method header and after the docstring.








Proper usage
 
 /**
  * This is is the description from the method that overriden the inherited method
  * @return the surface area of the box ( note: floor and ceiling are will be included )
  */

 @Override
  public double getArea(){
     return 2*(super.getArea() + height*(length+width));
    }

In this case, the documentation will reflect the proper documentation from the derived class.

  • Method Detail

    • getArea

      public double getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
Now, is there any other usage for this annotation? ", You might ask.  the answer is, yes.  Methods in the derived class can have any headers, so if the parent class method header changes, how would the child know that it also need to change.  The @Override annotation forces the compiler to match the method headers from the child to the parent.  Thus, it is a safety annotation that should always be used when overriding methods.

Test it:
Try to change the getArea method in the Rectangle class to return an integer not a double and see if you can still compile the code.

     public int getArea() {
          return (int)(length * width);
     }

Now, when you try to compile the application, it will not compile and the @Override annotation should remind you to update the failed methods.  So, fix the getArea method so it also return an integer.

  • Method Detail

    • getArea

      public int getArea()
      This is is the description from the method that overriden the inherited method
      Overrides:
      getArea in class Rectangle
      Returns:
      the surface area of the box ( note: floor and ceiling are will be included )
Now, you know it all!

Monday, July 9, 2018

Java Generics and the Anonymous Class

Interfaces can not be instantiated since interface methods do not have 
implemented methods, but methods can be implemented when the constructor is 
called. This can be done with generics as well, so keep practicing. 
 
public class HelloGeneric {
        public static void main(String[] args) {
  anonMethod();
 }
 
 public static void anonMethod() {
  // create a generic class with default access modifier and implement the 
                // interface
  class MyClass<T> implements HelloI<T> {
       public void printMsg(T m) {
           System.out.println(m + ".) Hello from anonymous class. ");
       }
  }
  MyClass<Integer> mc = new MyClass<Integer>();
  mc.printMsg(1);
 
  // implement methods in order to instantiate an interface without 
                // a separate implementing class
  HelloI<String> mc2 = new HelloI<String>() {
            public void printMsg(String m) {
       System.out.println(m + ".) Hello from another anonymous class. ");
     }
  };
  mc2.printMsg("Testing");
 }
}
 
Do not over complicate while you practice these concepts.  Just keep the code simple.
 
//generic interface to implement
public interface HelloI<T>
{
 public void printMsg(T m);
}

These anonymous classes show up as inner classes with an index value attached to them. 

Thursday, April 26, 2018

Recursive method design

In general, you need to think about a recursive method as any other type of problem you need to solve with loops.  Since recursive methods are nothing more than counter controlled while loops.  In every loop, you have to think about what to accomplish and what to update in addition to when to stop.

Let's take a simple example of adding values from 0 to some predetermined value.

First, you will need to design the algorithm based on your math knowledge. Thus, it might look like this,

As you can see the last term in the equation can be expressed in the terms of summing all values to n-1 and adding the next value to get the total sum of the values.  Thus, we have to understand that we have a previous value that exists.  Therefore, we have to stop when i equals n since there is no previous value before i==n, in that case the result is just n.

Let's solve this using regular loop:
 
Code Snippet
  1. public class Recursive{
  2.     public static void main(String args[]){
  3.         final int lowerLimit = 1;
  4.         int upperLimit = 10, sum = 0;
  5.         while (upperLimit > 0){
  6.             sum += upperLimit;
  7.             upperLimit--;
  8.         }
  9.         System.out.println(sum);
  10.     }
  11. }

Now, we can take this loop based solution and try to solve it by calling the function with a trivial solution like when the upper and lower limit is equal.

public class Recursive {
 public static void main(String args[]) {
  int upperLimit = 1, sum;
  sum = recurse(upperLimit);
  System.out.println(sum);
 }
 
 private static int recurse(int upperLimit) {
  int sum = 0;
  final int lowerLimit = 1;
  while (upperLimit >= lowerLimit) {
   sum += upperLimit;
   upperLimit--;
  }
  return sum;
 }
}

We now have solved a trivial value, next we need to see if we can solve the next value by adding all the previous values together.

public class Recursive {
 public static void main(String args[]) {
  int upperLimit = 2, sum;
  sum = recurse(upperLimit - 1) + 2;
  System.out.println(sum);
 }
 
 private static int recurse(int upperLimit) {
  int sum = 0;
  final int lowerLimit = 1;
  while (upperLimit >= lowerLimit) {
   sum += upperLimit;
   upperLimit--;
  }
  return sum;
 }
} 
 
So, now we proved that our method works with summing n-1 + n when a method is called with n-1.
Now, we can try to modify the method to call itself with n-1 values until it reaches 
the trivial value of lower limit.
 
Our goal is to call the method with n-1 as the parameter until we reach the trivial case 
that will reverse the course and return values that we'll add to n.
 
3 + f(2) -> 6
2 + f(1) -> 3
    f(1) -> 1 
public class Recursive {
 public static void main(String args[]) {
  int upperLimit = 10, sum;
  sum = recurse(upperLimit);
  System.out.println(sum);
 }
 
 private static int recurse(int upperLimit) {
  int sum = 0;
  final int lowerLimit = 1;
  if (upperLimit == lowerLimit)
   return upperLimit;
  else
   sum = upperLimit + recurse(--upperLimit);
  return sum;
 }
}
 
Now, we eliminated the loop due to recursive method calls and proved the original assumption of adding the upperLimit to the sum of all previous elements provides the sum of all elements.


 

Sunday, April 8, 2018

Design - Flowcharting and Pseudocode, function call and logic

Design is not just an annoying process in proper programming, but a necessary process to design code.
It can also eliminate misunderstanding in communication with others like in your marriage. Even in cooking, you would not start by turning on the oven to prepare dinner, but you would write down the shopping list before you left for the store and followed an ingredient list as you walked the isles. Planning is necessary when you want to accomplish something properly and design is necessary if you want someone else to create your idea, so you can come up with more ideas.



In all programming languages, we cover boolean logic and talk about the short circuits that exists with AND and OR boolean expressions. It is much easier to understand why they work if you can visualize its design. Boolean AND does not need to check the right side if the left side is false since there is not way to get a true result.  Only need to check the right side if the left side was true.
In boolean OR, there is no reason to check the right side if the left side is true since if will not be possible to get a false result.  Thus, you need to place the item to the left of the expression that will most likely fail in AND ( continuous range ) and to the left side that will most likely succeed in OR ( discrete ranges ).


 Even though there are may different ways to solve any problem, you still need to design its logic before beginning coding.  It is an art and a science to take an equation and turn it into an algorithm that someone can implement in code.  Design is the communication channel for those designing the algorithm ( highly educated engineers ) and those implementing the design ( trained coders ).

The design does not have to include the variable declarations since not every programming language is strongly typed language like C++ and Java is, but including variable declarations is not an error.  Header structure, libraries used, in-code comments, are never show up in program design.  Design is thee to guide the algorithm development, not the programming process.

// This program adds values from start to end one step at a time
//Author: Zoltan Szabo
//Version 1.0.0
#include <iostream>
 
using namespace std;
 
int main() {
 int start, end, sum = 0, count;
 
 do {                                     //validates to make sure user types in a positive value
  cout << "Enter a starting point: ";
  cin >> start;
 } while (start<0);
 
 do {                                     //validates to make sure the user types in larger value than the starting point
  cout << "Enter the ending point: ";
  cin >> end;
 } while (end<start);
 
 for (count = start; count <= end; count++) {
  sum += count;                         //accumulator to hold the sum
 }
 
 cout << "The sum of the values from " << start << " to " << end << " is " << sum << "." << endl;
 return 0;
} 
  
Java implementation of the same design might also include other use input validation by handling exceptions that would also not show up in the design of the methods.  Java also is a language that makes generating documentation much easier by the inclusion of docstrings that is up to the programmer to implement.

import java.util.Scanner;
/**
* The description for the class should describe the purpose of the class
* @author Zoltan Szabo
* @version 1.0.0
*/
public class SigmaStartEnd {
  /**
  * Every method needs description as well to help understand the purpose of the method
  * @param args Array of command line arguments
  * @return nothing
  * @throws In this case the method does not throw any exceptions
  */
  public static void main(String args[]) {
 Scanner keyboard = new Scanner(System.in);
 int start = 0, end = 0, sum = 0, count;
 try {
    do {     //validates to make sure user types in a positive value
  System.out.print("Enter a stating point: ");
  start = keyboard.nextInt();
    } while (start<0);
 
    do {    //validates to make sure the user types in larger value than the starting point
  System.out.print("Enter the ending point: ");
  end = keyboard.nextInt();
    } while (end<start);
 
    for (count = start; count <= end; count++) {
  sum += count;                         //accumulator to hold the sum
    }
 }
 catch (java.util.InputMismatchException e) {
    System.out.print("The value you entered was not a number. Bye.");
    System.exit(1);
 }
 System.out.print("The sum of the values from " + start + " to " + end + " is " + sum + "."); 
        keyboard.close();
   }// end of method
}// end of class

It does not matter which one you use, flowchart or pseudocode either one can help you analyze and understand code that was not written by you.  Since design is language independent, any code can be turned into design and into another language implemented code.

File Download ( full resolution ) 

Any code that is increased in complexity is better to manage if it is broken into functions.  Functions are essential management features and they also allow for code re-usability.  Function designs are lesser known features of designs since based on the implementing language, it might need to be noted is the function is being called by value or by reference.  There is no international standard how to design function calls, but this implementation is what I prefer to show reference based parameters. This should be carefully considered based on the programming language chosen for the implementation since object oriented programming languages might like Java might not distinguish the type of calls.

File Download ( full resolution ) 

Wednesday, November 22, 2017

Add Digits as Int, Array, Recursive

 There is not just one way to solve a problem.  Don't stop thinking about more than one way, think about performance, memory utilization, and efficiency of algorithm design.

public class AddDigits {
    private static int EXP=64;
    public static void main(String[] args) {
        System.out.printf("I added all (1234567) %d: \n",addDigits(1234567));
        System.out.printf("I added all (1234567) %d: \n",addDigits("1234567"));
        System.out.printf("I added all (1234567) %d: \n",addDigitsRec(1234567));
    }
    private static long addDigitsRec(long n){
        if(n<10){
            return n;
        }
        else{
            int index=0;
            for(;n/Math.pow(10,index)>9;index++){}
            return totalAdd(n,index);
        }
    }
    private static long totalAdd(long n, int index){
        long total=(int)(n/Math.pow(10,index));
        if(index==0){
            return total;
        }
        else
            total+=totalAdd((int)(n%Math.pow(10,index--)),index);
        return total;
    }
   
    private static long addDigits(long n){
        if(n<10){
            return n;
        }
        else{
            int index=0,total=0;
            for(;n/Math.pow(10,index)>9;index++){}
            while(index>-1){
                total+=(int)(n/Math.pow(10,index));
                n=(int)(n%Math.pow(10,index--));
            }
            return total;
        }
    }
    private static long addDigits(String n){
        if(n.length()==0){
            return 0;
        }
        else{
            long total=0;
            for(int index=0;index<n.length();index++){
                total+=Integer.parseInt(""+n.charAt(index));
            }
            return total;
        }
    }
}

Friday, November 17, 2017

Programmers are Lazy and Proud of It - Lambda Expression to the Rescue

Programmers are lazy by nature just like any other field in STEM ( Science, Technology, Engineering, and Math).  Lazy is not a derogatory term in this case,it is the desire to find an easy way to do repetitive and mundane tasks.  Simplification is also the goal for engineers to help other engineers not to make common mistakes.  We can see that trend clearly in loop designs.

First we had while loop that requires Loop Control Variable ( LCV ) priming, boolean logic design, and update to LCV.

        java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
        me.add(1);
        me.add(2);

        int count=0;                                                 //LCV priming
        while(count<me.size()){                             //boolean logic
            System.out.println(me.get(count));    

            count++;                                                  //update
        }


We had a problem since we had to keep track of these three components separately, so in a case of counter controlled loops, a simplified while loop was developed, called for loop.  It is a ternary operator using three arguments, all in one line, to simplify the while loop concept.

        for(int count=0;count<me.size();count++){
            System.out.println(me.get(count1));
        }


We still had problems with boolean logic and +/-1 mistakes processing data.  So, a simplified version of a for loop was developed, called advanced for loop.

        for(int i:me){
            System.out.println(i);
        }


Hiding the complexities and making things simple is an advanced concept, it is a form of oxymoron in geeks world. Thus, having an input, hiding the complexities of processing the input, and having the desired output is an aim for quicker program development with less logical errors or mistakes.  This hiding desire is not a digital age child, it is a mathematical theory and the base for lambda calculus.


Lambda calculus (also written as λ-calculus) is a formal system in mathematical logic for expressing computation based on function abstraction and application using variable binding and substitution. It is a universal model of computation that can be used to simulate any Turing machine and was first introduced by mathematician Alonzo Church in the 1930s as part of his research of the foundations of mathematics.
Lambda calculus consists of constructing lambda terms and performing reduction operations on them. In the simplest form of lambda calculus, terms are built using only the following rules:


The Lambda calculus is an abstract mathematical theory of computation, involving functions. The lambda calculus can be thought of as the theoretical foundation of functional programming. It is a Turing complete language; that is to say, any machine which can compute the lambda calculus can compute everything a Turing machine can (and vice versa).
The notation is based on function abstraction and application based on variable binding and substitution. If you have done same basic programming already, you might be familiar with lambda functions or anonymous functions already. They are featured in Haskell, Mathematica, Python and recent versions of C++ too. In this wiki, we will mostly stick to Haskell.


This concept of process hiding starts by understanding anonymous classes.  As you can see below, class can override methods without changing the original class permanently. 

class Perform{
    public int doubleIt(int i){
        return 2*i;
    }
}
public class HiddenProcess{
    public static void main(String args[]){
        Perform myNumber=new Perform() 
            {
                private String addedAttribute="My Added Message";
                public int doubleIt(int i){
                    return i+i;
                }
            }
;
       System.out.println(myNumber.doubleIt(3));
    }
}

The next concept we need to understand is interfaces.  Interfaces can not be instantiated without a class implementing the interface defined method headers.

interface MyWish{
    void complete(int a);  
}
class MyWishRealize implements MyWish{
    public void complete( int a){
        System.out.println(3);
    }

}
public class HiddenProcess{
    public static void main(String args[]){
        MyWishRealize wishOne=new MyWishRealize();
    }
}
So, we can override and implement methods in anonymous classes therefore we can override methods in classes implementing interfaces.

interface MyWish{
    void complete(int a);  
}
class MyWishRealize implements MyWish{
    public void complete( int a){
        System.out.println(3);
    }
}
public class HiddenProcess{
    public static void main(String args[]){
        MyWishRealize wishOne=new MyWishRealize(){
                public void complete(int a ){
                    System.out.println(3000);
                }
           };

        MyWishRealize wishTwo=new MyWishRealize(){
                public void complete(int a ){
                    System.out.println(6000);
                }
            };

    }
}


So, we can also implement an interface using an anonymous class, so we do not need to create an extra class just to implement the interface.

interface MyWish{
    void complete(int a);  
}
public class HiddenProcess{
    public static void main(String args[]){
        MyWish gift= new MyWish(){
                public void complete( int a){
                    System.out.println("Hello "+a);
                }
            };

    }
}

But the simplified structure can be even more simplified by lambda expression like this;
interface MyWish{
    void complete(int a);  
}
public class HiddenProcess{
    public static void main(String args[]){
        MyWish gift1=(i)->System.out.println("Hello "+i);
    }
}


Lambda Expression 

Prior to Java 1.8, if you looked at the API for ArrayList, you did not have a method to process the array with forEach mehod.

void
ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
E
get(int index)
Returns the element at the specified position in this list.
int
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.

Java 1.8 added that method to the available method's list to simplify processing the array.

void
ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
void
forEach(Consumer<? super E> action)
Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.
E
get(int index)
Returns the element at the specified position in this list.
int
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.


forEach method is based on the iterable interface and takes a consumer interface as its parameter.·         

forEach


public void forEach(Consumer<? super E> action)

Description copied from interface: Iterable

Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified). Exceptions thrown by the action are relayed to the caller.

Specified by:

forEach in interface Iterable<E>

Parameters:

action - The action to be performed for each element


Iterable inerface's forEach method gives us the reference to the enhanced for loop and to the idea of simplifying its operation.·       

 forEach


default void forEach(Consumer<? super T> action)

Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified). Exceptions thrown by the action are relayed to the caller.

Implementation Requirements:

The default implementation behaves as if:

 
     for (T t : this)
         action.accept(t);
 

Parameters:action - The action to be performed for each element

      Throws:NullPointerException - if the specified action is null

         Since:1.8

The Consumer interface has the method accept that takes any dataType object and performs the given operation on that dataType.  Since Consumer is an interface, a class needs to implement its method accept. 

java.util.function

Interface Consumer<T>

Type Parameters: 
      T - the type of the input to the operation

All Known Subinterfaces:Stream.Builder<T>

Functional Interface:This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

Modifier and Type
Method and Description
void
accept(T t)
Performs this operation on the given argument.



The following code demonstrates the implementation of Consumer interface. ( Note: For simple introduction to Java's Generics - read my article - http://intro2cs-java.blogspot.com/2017/03/generic-getting-started.html )

class implementConsumer<T> implements java.util.function.Consumer<T> {
 public void accept(T i){
     System.out.println(i);
    }

}
public class HiddenProcess{
    public static void main(String args[]){
        implementConsumer<String> value=new implementConsumer<>();
        value.accept("Hello");

    }
}


So, how can we do the same without using the extra class implementConsumer?  WE should use anonymous inner class to accomplish that for this interface. But we would need to create an implementation for each dataType and that would be very annoying.

public class HiddenProcess{
    public static void main(String args[]){
        java.util.function.Consumer<String> value=new java.util.function.Consumer<String>(){
                public void accept(String i){
                    System.out.println(i);
                }
            };

        value.accept("Hello");
    }
}


We would need to create an implementation for ArrayList for each dataType it is instantiated and that would annoy us as well.

public class HiddenProcess{
    public static void main(String args[]){
        java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
        me.add(1);
        me.add(2);
        java.util.function.Consumer<java.util.ArrayList<Integer>> value=new       java.util.function.Consumer<java.util.ArrayList<Integer>>(){
                public void accept(java.util.ArrayList<Integer> i){
                   for(int val:i)
                    System.out.println(val);
                }
            };

        value.accept(me);
    }
}

At the end, we can simplify all this with our lambda expression that works for every dataType and the syntax is simplified to a single line of code.  Isn't that cool!!!

public class HiddenProcess{
    public static void main(String args[]){
        java.util.ArrayList<Integer> me=new java.util.ArrayList<>();
        me.add(1);
        me.add(2);
        me.forEach(i->System.out.println(i));
    }
}

Conclusion

Being lazy means innovation toward an advanced society, so be proud of it and keep innovating!