Monday, 27 June 2016

What are P, NP, NP-complete, and NP-hard?

Problems in class P can be solved with algorithms that run in polynomial time.

Say you have an algorithm that finds the smallest integer in an array.  One way to do this is by iterating over all the integers of the array and keeping track of the smallest number you've seen up to that point.  Every time you look at an element, you compare it to the current minimum, and if it's smaller, you update the minimum.

How long does this take?  Let's say there are n elements in the array.  For every element the algorithm has to perform a constant number of operations.  Therefore we can say that the algorithm runs in O(n) time, or that the runtime is a linear function of how many elements are in the array.*  So this algorithm runs in linear time.

You can also have algorithms that run in quadratic time (O(n^2)), exponential time (O(2^n)), or even logarithmic time (O(log n)).  Binary search (on a balanced tree) runs in logarithmic time because the height of the binary search tree is a logarithmic function of the number of elements in the tree.

If the running time is some polynomial function of the size of the input**, for instance if the algorithm runs in linear time or quadratic time or cubic time, then we say the algorithm runs in polynomial time and the problem it solves is in class P.

NP

Now there are a lot of programs that don't (necessarily) run in polynomial time on a regular computer, but do run in polynomial time on a nondeterministic Turing machine.  These programs solve problems in NP, which stands for nondeterministic polynomial time.  A nondeterministic Turing machine can do everything a regular computer can and more.***  This means all problems in P are also in NP.

An equivalent way to define NP is by pointing to the problems that can be verified in polynomial time.  This means there is not necessarily a polynomial-time way to find a solution, but once you have a solution it only takes polynomial time to verify that it is correct.

Some people think P = NP, which means any problem that can be verified in polynomial time can also be solved in polynomial time and vice versa.  If they could prove this, it would revolutionize computer science because people would be able to construct faster algorithms for a lot of important problems. 


Ex: Subset Sum, 0-1 knapsack etc.
 
NP-hard

What does NP-hard mean?  A lot of times you can solve a problem by reducing it to a different problem.  I can reduce Problem B to Problem A if, given a solution to Problem A, I can easily construct a solution to Problem B.  (In this case, "easily" means "in polynomial time.")

If a problem is NP-hard, this means I can reduce any problem in NP to that problem.  This means if I can solve that problem, I can easily solve any problem in NP.  If we could solve an NP-hard problem in polynomial time, this would prove P = NP.






Ex: Travelling Salesman, Subset Sum etc.
 
NP-complete

A problem is NP-complete if the problem is both

  • NP-hard, and
  • in NP.

Note: The interesting observation here is that, we are still unable to find a single problem that is NP, but not NP-Hard.

Thursday, 31 December 2015

Sequence Control

  1. Sequence control
Sequence control : the control of the order of execution of the operations both primitive and user defined.
Implicit: determined by the order of the statements in the source program
or by the built-in execution model
Explicit: the programmer uses statements to change the order of execution
(e.g. uses If statement)
  1. Levels of sequence control
Expressions: computing expressions using precedence rules and parentheses.
Statements: sequential execution, conditional and iteration statements.
Declarative programming: an execution model that does not depend on the order
of the statements in the source program.
Subprograms: transfer control from one program to another.
  1. Sequencing with expressions
The issue: given a set of operations and an expression involving these operations,
what is the sequence of performing the operations?
How is the sequence defined, and how is it represented?
An operation is defined in terms of an operator and operands.
The number of operands determines the arity of the operator.
Basic sequence-control mechanism: functional compositionGiven an operation with its operands, the operands may be:
  • Constants
  • Data objects
  • Other operations
Example 1: 3 * (var1 + 5)
    operation - multiplication, operator: *, arity - 2
    operand 1: constant (3)
    operand 2: operation addition
    operand1: data object (var1)
    operand 2: constant (5)
Functional compositions imposes a tree structure on the expression,
where we have one main operation, decomposable into an operator and operands.
In a parenthesized expression the main operation is clearly indicated.
However we may have expressions without parentheses.
Example 2: 3* var1 +5
Question: is the example equivalent to the above one?
Example 3: 3 + var1 +5
Question: is this equivalent to (3 + var1) + 5, or to 3 + (var1 + 5) ?
In order to answer the questions we need to know:
  • Operator's precedence
  • Operator's associativity
Precedence concerns the order of applying operations, associativity deals with the order of operations of same precedence.
Precedence and associativity are defined when the language is defined - within the semantic rules for expressions.
3. 1. Arithmetic operations / expressionsIn arithmetic expressions the standard precedence and associativity of operations
are applied to obtain the tree structure of the expression.
Linear representation of the expression tree:
  • Prefix notation
  • Postfix notation
  • Infix notation
Prefix and postfix notations are parentheses-free.
There are algorithms to evaluate prefix and postfix expressions and algorithms to convert an infix expression into prefix/postfix notation, according to the operators' precedence and associativity.
3. 2. Other expressionsLanguages may have some specific operations, e.g. for processing arrays and vectors, built-in or user defined. Precedence and associativity still need to be defined - explicitly in the language definition or implicitly in the language implementation.
3. 3. Execution-time representation of expressions
  • Machine code sequence
  • Tree structures - software simulation
  • Prefix or postfix form - requires stack, executed by an interpreter.
3. 4. Evaluation of tree representationEager evaluation - evaluate all operands before applying operators.
Lazy evaluation - first evaluate all operands and then apply operations
Problems:
  • Side effects - some operations may change operands of other operations.
  • Error conditions - may depend on the evaluation strategy (eager or lazy evaluation)
  • Boolean expressions - results may differ depending on the evaluation strategy.
  1. Statement level sequence control
4. 1. Forms of statement-level control
  • Composition – Statements are executed in the order they appear on the page.
  • Alternation – Two sequences form alternatives so one sequence or the other 
  • sequence is executed but not both. (conditionals)
  • Iteration – A sequence of statements that are executed repeatedly.
  • Explicit Sequence Control
goto Xif Y goto X – transfer control to the statement labeled X if Y is true.
break4. 2. Structured programming design
  1. Hierarchical design of program structures
  1. Representation of hierarchical design directly in the program text 
  1. using "structured" control statements.
  1. The textual sequence corresponds to the execution sequence
  1. Use of single-purpose groups of statements
4. 3. "Structured" control statements
  1. Compound statements
Typical syntax:
begin
    statement1;
    statement2;
    ...
    end;
Execute each statement in sequence.
Sometimes (e.g., C) { ... } used instead of begin ... end
  1. Conditional statements
if expression then statement1 else statement2
if expression then statement1
If we need to make a choice among many alternatives
nested if statements
case statements
Example :
case Tag is
    when 0 => begin
    statement0
      end;
when 1 => begin
    statement1
      end;
when 2 => begin
    statement2
      end;
when others => begin
    statement3
       end;
end case
Implementation: jump and branch machine instructions, jump table implementation for case statements (see fig. 8.7)
  1. Iteration statements
Simple repetition (for loop) Specify a count of the number of times to execute a loop:
Examples:
perform statement K times;
for I=1 to 10 do statement;
for(I=0;  I<10;  I++) statement;
Repetition while condition holds
while expression do statement; - Evaluate expression and if true execute statement. then repeat process.
repeat statement until expression; - Execute statement and then evaluate expression. Quit if expression is true.
C++ for loop functionally is equivalent to repetition while condition holds
by T. Pratt and M. ZelkowitzProblems with structured sequence control:Multiple exit loops
Exceptional conditions
Do-while-do structure







Characteristics of Programming Languages

  • Readability: A good high-level language will allow programs to be written in some ways that resemble a quite-English description of the underlying algorithms. If care is taken, the coding may be done in a way that is essentially self-documenting.
  • Portability: High-level languages, being essentially machine independent, should be able to develop portable software.
  • Naturalness:- A good language should be natural for the application area, for which it has been designed. That is, it should provide appropriate operators, data structures,  control structures, and a natural syntax to facilitate the users to code their problem easily and efficiently.  
  • Generality: Most high-level languages allow the writing of a wide variety of programs, thus relieving the programmer of the need to become expert in many diverse languages.
  • Brevity: Language should have the ability to implement the algorithm with less amount of code. Programs expressed in high-level languages are often considerably shorter than their low-level equivalents.
  • Error checking: Being human, a programmer is likely to make many mistakes in the development of a computer program. Many high-level languages enforce a great deal of error checking both at compile-time and at run-time.
  • Cost: The ultimate cost of a programming language is a function of many of its characteristics.
  • Familiar notation: A language should have familiar notation, so it can be understood by most of the programmers.
  • Quick translation: It should admit quick translation.
  • Efficiency: Programs written in a good programming language are efficiently translated into machine code, are efficiently executed, and acquire as little space in the memory as possible.  
  • Modularity: It is desirable that programs can be developed in the language as a collection of separately compiled modules, with appropriate mechanisms for ensuring self-consistency between these modules.
  • Widely available: Language should be widely available and it should be possible to provide translators for all the major machines and for all the major operating systems. 

Dataflow Programming Language

   A programming paradigm in which computation is modelled as a directed graph (which may or may not contain cycles), the nodes of which are either data sources (producers of data), data sinks (consumers), or "processing elements" which compute some function; and the arcs of which represent dataflow between nodes.

   Dataflow programming languages share some features of functional languages, and were generally developed in order to bring some functional concepts to a language more suitable for numeric processing.

Representation

Dataflow programs start with an input, perhaps the command line parameters, and illustrate how that data is used and modified. The flow of data is explicit, often visually illustrated as a line or pipe.

In terms of encoding, a dataflow program might be implemented as a hash table, with uniquely identified inputs as the keys, used to look up pointers to the instructions. When any operation completes, the program scans down the list of operations until it finds the first operation where all inputs are currently valid, and runs it. When that operation finishes, it will typically output data, thereby making another operation become valid.

 

Introduction To Lambda Calculus

1. Introduction

   The Lambda Calculus was developed by Alonzo Church in the 1930s and published in 1941 as "The Calculi Of Lambda Conversion". It became important, along with Turing machines, in the development of computation theory, and is the theoretical basis of all functional programming languages, such as Lisp, Haskell and ML.

   Lambda calculus is a formal, abstract language where all functions are defined without giving a name. We can understand the foundations of functional programming by studying the properties of this formal language.

   It should be noted that the lambda notation is not frequently used in practical Lisp programming. The reason is simple: the use of a name is more convenient to refer to a function. Reference to a function without name is difficult for practical programming if you want the function to be called many times. However, as we have said, our interest lies in the role that lambda calculus plays as a foundation of functional programming. Once we understand an abstract model of computation, we can always develop a language based on it. 

   It does not have any complicated formulae or operations. All it ever does is taking a line of letters (or symbols), and performing a little cut and paste operation on it. As you will see, the Lambda Calculus can compute everything that can be computed, just with a very simple cut and paste.

2. Language

Syntax of lambda calculus
 
The language of lambda calculus is simply defined as:
[function]      := (lambda (x) [expression])
[application]   := ([expression] [expression])
[expression]    := [identifiers] | [application] | [function]
[identifiers]   := a | b | ...

    A line of symbols is called an expression. It might look like this: (λx.xy) (ab)
We only have the following symbols:

  • Single letters (like a, b, c, d...), which are called variables. An expression can be a single letter, or several letters in a row. More generally, we can write any two or more expressions together to get another expression.
  • Parentheses: ( ). Parentheses can be used to indicate that some part of an expression belongs together (just as the braces around this part of the sentence make it belong together). Where we don't have parentheses, we look at expressions simply from left to right.
  • The greek letter λ (pronounced, of course: Lambda), and the dot: . With λ and the dot, we can write functions. A function starts always with the λ and a variable, followed by a dot, and then comes an expression. The λ does not have any complicated meaning: it just says that a function starts here. The λ-variable-. part of a function is called its head, and the remainder (the expression) is called the body.     


Q: What is the value or meaning of a variable? 
A: None. Variables do not stand for anything. They are just empty names. Even the name is unimportant. The only thing that matters is: when two variables have the same name, they are the same. You can rename variables all you want, without changing the expression.
Q: What does a function calculate? 
A: Nothing, really. It is just a kind of expression, with a head and a body. It just stands there. The only thing we can do with it is to resolve it.
Q: Why "λ"? 
A: An accident, perhaps. Initially, Alonzo Church just drew a little roof to mark the head variable, like this: (ŷ xy) ab. In the typed manuscript, he put the roof in front of the head, so it became (⋀y.xy) ab. The typesetter turned it into (λy.xy) abwhich is visually close enough.

    Slightly more formally, we can say: All variables are lambda terms (a valid expression in the lambda calculus). If x and are lambda terms, then (x y) is a lambda term, and (λx.y) is a lambda term. From these three rules, we can construct all valid expressions. If we also agree to read all lambda expressions from left to right, we can omit a few of the parenthesis: (λy.xy) ab is the simplified version of (((λy.(x y)) a) b).

Cut & Paste

    Functions can be resolved if they are followed by another expression. The resolution works by taking the variable mentioned in the head, and replacing all of its occurrences within the body with the expression after the function. We cut the expression after the function, and paste it into the body, in every place indicated by the head. Having done that, we throw the head away, because it has served its purpose: telling us which variable to replace.
  
   The resolution of functions is the only thing we can ever do in the Lambda Calculus. Once we have gotten rid of all the lambdas, or if there are no more expressions after the remaining functions, we cannot replace anything any more. We can go home now. 

      Q: Can functions contain other functions?
   
      A: Absolutely. Functions are expressions, and expressions can contain other expressions, so functions can be parts of the bodies of other functions, or be part of the replacing expression. In fact, we have expressions like λx.λy.xzy so often that we like to abbreviate them as λxy.xzy. This means that we will try to replace the first variable in the head (x) with the first expression after the body (xzy), the second variable (y) with the next one after that, and so on.  The variables mentioned in the head (the one tagged for replacement) are called bound variables. Unmentioned variables are free variables. Because functions can be part of other functions, a variable may be both bound and free in the same expression.

Church Numerals

    So if we want to have numbers, we have to encode them as functions. Thankfully, Alonzo Church already came up with such an encoding, where the value of a numeral is equivalent to the number of times a function is applied to an argument. This can be written as λs.λz. sn z, where n is the natural number represented and sn means function s composed with itself n times (we’ll say “applied n times” for short).
Thus the first few natural numbers are encoded as follows:
  • 0 = λs.λz. z the function s is applied to the argument z zero times
  • 1 = λs.λz. s z the function s is applied once
  • 2 = λs.λz. s (s z) the function s is applied twice
(the names s and z are short for successor and zero)

    Lets also quickly look at how we can write simple functions with numbers.
succ = λn.λs.λz. s (n s z) (n + 1)
succ adds 1 to a number. Since a number n is defined as a function that applies the 1st argument to the 2nd argument n times, the result should be a function that applies the 1st argument one more time. When you substitute the variable n in succ with a value x, that’s what you get: a function that applies s one more time than x would:
(λn.λs.λz. s (n s z)) x → λs.λz. s (x s z)
    Similarly, we define a + b so that it returns a function applying s b times and then a times
add = λa.λb.λs.λz. a s (b s z) (a + b)
    To understand this more clearly, lets substitute values x and y for a and b:
(λa.λb.λs.λz. a s (b s z)) x y →
(λb.λs.λz. x s (b s z)) y →
λs.λz. x s (y s z)
    As we can see, after applying x and y, the result is still a function that looks similar in shape to our original definition of numbers. It applies s to z y times, then applies s to the result x more times. Multiplication can be defined in a way that looks even simpler than the addition above:
mul = λa.λb.λs. a b s (a * b)
Substituting x and y gives us:
(λa.λb.λs. a b s) x y →
(λb.λs. x b s) y →
λs. x y s
    It looks simpler, but is perhaps harder to grasp immediately: we used a trick and left out the z argument. Now the shape of the resulting function is different — it applies y to s x times, but what does it mean to apply a number y to just one argument? Remember that if y is a number, it must perform a computation of the shape λs.λz. sy z. If we apply this to the s in the multiplication x times, we get the following (renaming the outer s to s’ to distinguish from the inner s):
λs’. (λs.λz. sy z)x s’
   So in this case we see that the 2nd argument z is there in y, but we apply y only to s. This is similar to partial application in many languages. Lets see what happens if x = y = 1:
λs’. (λs.λz. s1 z)1 s’ =
λs’. (λs.λz. s z) s’ →
λs’.λz. s’ z

(this is equivalent to the definition of 1)
Lets do 2 * 2 as well, where the substitutions become more complex and we rename some variables to distinguish similarly-named ones:
λs’. (λs.λz. s2 z)2 s’ =
λs’. (λs.λz. s (s z))2 s’ =
λs’. (λs.λz. s (s z)) ((λs’’.λz’’. s’’ (s’’ z’’)) s’) →
λs’. (λs.λz. s (s z)) (λz’’. s’ (s’ z’’)) →
λs’. λz. (λz’’. s’ (s’ z’’)) ((λz’’. s’ (s’ z’’)) z) →
λs’. λz. (λz’’. s’ (s’ z’’)) (s’ (s’ z)) →
λs’. λz. s’ (s’ (s’ (s’ z))))

(this is equivalent to definition of 4)
To recap, we defined multiplication using partial application of lambdas, without mentioning the second argument z that we usually had in numbers, but the end result still has the correct shape. We could also have defined multiplication in a more verbose way that includes the z argument. Give it a try, or try to come up with an alternative definition of multiplication that uses succ or add.

Church Booleans

   Booleans can also be encoded as functions:
  • true = λt.λf.t 2-arg function returning the 1st arg
  • false = λt.λf.f 2-arg function returning the 2nd arg
    Basically, the booleans represent if-then-else expressions. They both take two arguments, true returns the first (then) and false returns the second (else). We’ll take a look at some example programs with booleans in the next posts.



 

 
 

Thursday, 24 December 2015

OpenGL Primitives

   Primitives are basic shapes that you can easily draw. It can be a triangle, a square, or even a single point.

   First, let me mention that OpenGL is a low level API, this means that it has no support for drawing complex geometrical objects. It is the programmer’s job to combine the geometrical primitives from OpenGL in complex shapes and bodies. The basic geometrical primitives that the core OpenGL profile provide to us are points, lines and triangles.

   Each primitive has at least one vertex. What is a vertex exactly? Is it one of the points in a polygon or is it a stand-alone point in space? Well it can be both, depending on how you think about it. With points, vertex is just that - the point.
  • A line has only 2 vertices - its starting point and its ending point.
  • With polygons, there should be more than 2 vertices since polygons are surfaces defined by more or equal to 3 vertices residing on the same plane. 
  • A triangle is, for instance, a polygon with 3 vertices.  

   Note that a 3D cube cannot be considered a primitive. Generally, primitives restrict themselves to triangles. A four-sided polygon can generate a quad but that quad will still be made out of 2 polygons. Points and lines can also be considered primitives.

Immediate Mode

   The easiest way to do drawing in OpenGL is using the Immediate Mode. For this, you use the glBegin() function which takes as one parameter the “mode” or type of object you want to draw.

   Here is a list of the possible modes and what they mean:

GL_POINTS Draws points on screen. Every vertex specified is a point.
GL_LINES Draws lines on screen. Every two vertices specified compose a line.
GL_LINE_STRIP Draws connected lines on screen. Every vertex specified after first two are connected.
GL_LINE_LOOP Draws connected lines on screen. The last vertex specified is connected to first vertex.
GL_TRIANGLES Draws triangles on screen. Every three vertices specified compose a triangle.
GL_TRIANGLE_STRIP Draws connected triangles on screen. Every vertex specified after first three vertices creates a triangle.
GL_TRIANGLE_FAN Draws connected triangles like GL_TRIANGLE_STRIP, except draws triangles in fan shape.
GL_QUADS Draws quadrilaterals (4 – sided shapes) on screen. Every four vertices specified compose a quadrilateral.
GL_QUAD_STRIP Draws connected quadrilaterals on screen. Every two vertices specified after first four compose a connected quadrilateral.
GL_POLYGON Draws a polygon on screen. Polygon can be composed of as many sides as you want.

   All the shapes that you can think of either are, or can be broken down into, geometric primitives. For example a pyramid can be broken down into a few triangles. All the geometry that you render in OpenGL is constructed of primitives and there are quite a few available to you. Below is a list of the OpenGL primitive types available and an example of how they can look with an example set of vertices:



    The main function (and probably the most used OpenGL function) is function named glVertex. This function defines a point (or a vertex) in your 3D world and it can vary from receiving 2 up to 4 coordinates.
    Let's take a look at these variations:

   glVertex2f(100.0f, 150.0f); defines a point at x = 100, y = 150, z = 0; this function takes only 2 parameters, z is always 0. glVertex2f can be used in special cases and won't be used a lot unless you're working with pseudo-2D sprites or triangles and points that always have to be constrained by the depth coordinate.

   glVertex3f(100.0f, 150.0f, -25.0f); defines a point at x = 100, y = 150, z = -25.0f; this function takes 3 parameters, defining a fully 3D point in your world. This function will be used a lot to define any kind of shapes you will possibly want.

   glVertex4f(100.0f, 150.0f, -25.0f, 1.0f); this is the same as glVertex3f, the only difference is in the last coordinate that specifies a scaling factor. The scaling factor is set to 1.0f by default. This won't make a lot of use and I'm not going to explain this function in details. It can be used to make your 3D points look thicker than one pixel. I don't want to sound pathetic but why would you want to use that functionality?

   Anyway, glVertex alone won't draw anything on the screen, it merely defines a vertex, usually of a more complex object. To really start displaying something on the screen you will have to use two additional functions.
 
   These functions are: glBegin(int mode) and glEnd( void ).

    glBegin and glEnd delimit the vertices of a primitive or a group of like primitives. What this means is that everytime you want to draw a primitive on the screen you will first have to call glBegin, specifying what kind of primitive it is that you want to draw in the mode parameter of glBegin, and then list all vertices one by one (by sequentially calling glVertex) and finally call glEnd to let OpenGL know that you're done drawing a primitive.

Drawing Points

  Lets do an example with the simplest mode, the GL_POINTS. When drawing points using OpenGL, the default size of the points is 1 pixel wide and high. This would be very hard to see when you run the program. To edit the size of the point you want to draw, you use the glPointSize() function which takes as one parameter the size of the point you want.

  Now in the Render() function, before you write the glBegin() code, we will set the point size to be 10 pixels in size:

    glPointSize(10.0f); 
 
   After that, any drawing of points will be drawn 10 pixels wide and high. Now write the glBegin() function with the GL_POINTS mode parameter. Then after that specify the vertices you want to use using the glVertex3f() function. For this example, we want the upper – right corner (1.0,1.0,0.0) and the lower – left corner (-1.0,-1.0,0.0) of the screen to have a point. After drawing those two points, make sure to end the drawing with the glEnd() function:

    glBegin(GL_POINTS); //starts drawing of points
      glVertex3f(1.0f,1.0f,0.0f);//upper-right corner
      glVertex3f(-1.0f,-1.0f,0.0f);//lower-left corner
    glEnd();//end drawing of points 
 

Drawing Triangles

   Triangles are composed of three vertices. For this example we are going to use the regular GL_TRIANGLES mode to draw two triangles side by side.

   First we want a triangle to the left. So we need three vertices on the left side representing one triangle and three vertices on the right side of the window representing the second triangle. Note that you don’t need two glBegin() functions to draw two triangles. Since the mode GL_TRIANGLES is plural, it can handle more than one triangle in between one glBegin() and glEnd() function call:
 



   Note that I wrote on the bottom – right corner of the diagram the coordinates of the vertices. Here is the code to draw these two triangles:

    glBegin(GL_TRIANGLES);//start drawing triangles
      glVertex3f(-1.0f,-0.25f,0.0f);//triangle one first vertex
      glVertex3f(-0.5f,-0.25f,0.0f);//triangle one second vertex
      glVertex3f(-0.75f,0.25f,0.0f);//triangle one third vertex
      //drawing a new triangle
      glVertex3f(0.5f,-0.25f,0.0f);//triangle two first vertex
      glVertex3f(1.0f,-0.25f,0.0f);//triangle two second vertex
      glVertex3f(0.75f,0.25f,0.0f);//triangle two third vertex
    glEnd();//end drawing of triangles

Wednesday, 23 December 2015

JavaBean

   JavaBean is a Java class that is mainly responsible for holding on to some data without a large degree of functionality built into the class.

   Typically, a JavaBean is a Java class that:
  1. Implements the Serializable interface
  2. Exposes its properties via getter/setter methods
  3. Has a no-argument constructor
  • Implementing the Serializable interface is required if you have a need to save the object (with its data) somewhere (file system, database, refrigerator, etc).
  •  It's standard practice is to allow the manipulation of the properties within the class via getter/setter methods. 
  • Sometimes we may add further methods to a JavaBean class besides the standard getter/setter methods if the nature of particular functionality makes sense to be encapsulated within the bean class, but we make an effort to make such changes the exception to the rule, since this can dirty up your bean classes, which can spread out functionality within your application which can make code maintainability more difficult.

Simple example of java bean class

  1. //Employee.java  
  2.   
  3. package mypack;  
  4. public class Employee implements java.io.Serializable
  5. {  
  6.    private int id;  
  7.    private String name;  
  8.   
  9.    public Employee()
  10.   {
  11.   }  
  12.   
  13.    public void setId(int id)
  14.   {
  15.      this.id=id;
  16.   }  
  17.   
  18.   public int getId()
  19.  {
  20.     return id;
  21.  }  
  22.   
  23.   public void setName(String name)
  24.  {
  25.     this.name=name;
  26.  }  
  27.   
  28.   public String getName()
  29.   {
  30.     return name;
  31.   }  

How to access the java bean class?

To access the java bean class, we should use getter and setter methods.
  1. <jsp:useBean id="id" class="bean's class" scope="bean's scope">
       <jsp:setProperty name="bean's id" property="property name"  
                        value="value"/>
       <jsp:getProperty name="bean's id" property="property name"/>
       ...........
    </jsp:useBean>

JavaBeans Properties:

   A JavaBean property is a named attribute that can be accessed by the user of the object. The attribute can be of any Java data type, including classes that you define.
  A JavaBean property may be read, write, read only, or write only. JavaBean properties are accessed through two methods in the JavaBean's implementation class:
MethodDescription
getPropertyName()For example, if property name is firstName, your method name would be getFirstName() to read that property. This method is called accessor.
setPropertyName()For example, if property name is firstName, your method name would be setFirstName() to write that property. This method is called mutator.
    A read-only attribute will have only a getPropertyName() method, and a write-only attribute will have only a setPropertyName() method.