Procedural Programming Concepts in Java - PowerPoint PPT Presentation

1 / 70
About This Presentation
Title:

Procedural Programming Concepts in Java

Description:

All of these are associated with what is called Linear Execution ... Dangling else. The structure of a Java if statement allows for an interesting special case: ... – PowerPoint PPT presentation

Number of Views:47
Avg rating:3.0/5.0
Slides: 71
Provided by: Knigh7
Category:

less

Transcript and Presenter's Notes

Title: Procedural Programming Concepts in Java


1
Procedural Programming Concepts in Java
  • PJ Dillon
  • CS401

Slides adapted from Dr. Ramirez
2
Control Statements
  • Other statements weve already seen
  • Declaration Statement
  • Assignment Statement
  • Method Call
  • All of these are associated with what is called
    Linear Execution (Also called Execution Flow)
  • Each statement in a program must be executed one
    after another
  • No control over which statements are executed
  • The real power of a program is the ability to
    make decisions
  • Can execute or re-execute a set of statements
    based on the decision

3
Control Statements
  • Control Statements provide the means to control
    the execution of different statements
  • Allow for 2 important types of execution
  • Conditional execution
  • Statements may or may not execute
  • Iterative execution
  • Statements may execute more than once

4
Execution Flow
Linear Execution
Conditional Execution
Iterative Execution
5
Boolean Expressions
  • Key to many control statements in Java are
    boolean expressions
  • Expressions whose result is true or false
  • true and false are predefined literals in Java
  • Can be created using one or more relational
    operators and logical operators
  • Relational operators
  • Used to compare (i.e. relate) two primitive
    values
  • Result is true or false based on values and the
    comparison that is asserted
  • Ex 6 lt 10 -- true because 6 IS less than 10
  • 7 ! 7 -- false because 7 IS NOT not
    equal to 7

6
Boolean Expressions
  • Java has 6 relational operatorslt lt gt gt
    !
  • Some boolean expressions are more complicated
    than just a simple relational operation
  • These expressions require logical operators
  • Operate on boolean values, generating a new
    boolean value as a result
  • !
  • Recall their values from a truth table

7
Boolean Expressions
  • Lets look at some examples
  • int i 10, j 15, k 20
  • double x 10.0, y 3.333333 z 100.0
  • i lt j j lt k x lt y
  • (i / 3) y
  • (x / 3) y
  • !(x ! i)

8
If statement
  • The if statement is very intuitive
  • if (booleanexpression)
  • lttrue optiongt
  • else
  • ltfalse optiongt
  • Each of lttrue optiongt and ltfalse optiongt can be
    any Java statement, including a block
  • Java blocks are delimited by and can contain
    any number of statements
  • else ltfalse optiongt is optional
  • Note parens around booleanexpression - required

9
If statement
  • Nested ifs
  • Since both lttrue optiongt and ltfalse optiongt can
    be any Java statement, they can certainly be if
    statements
  • This allows us to create nested if statements
  • We can nest on lttrue optiongt, on ltfalse optiongt
    or both
  • Enables us to test multiple conditions and to
    have a different result for each possibility

10
If statement
  • Dangling else
  • The structure of a Java if statement allows for
    an interesting special case
  • if (grade gt 95)
  • if (extraCredit)
  • System.out.println(A)
  • else
  • System.out.println(?)
  • Question is the ltfalse optiongt for condition1 or
    condition2?
  • As shown above it will ALWAYS be for condition2
  • Rule is that an else will always be associated
    with the closest unassociated, non-terminated if

11
If statement
  • Thus, there is no problem for the computer
  • Problem is if the programmer does not understand
    the rule
  • Result is a LOGIC ERROR
  • Logic errors can be very problematic and
    difficult to correct
  • Unlike a syntax error, which prevents the program
    from being compiled, with a logic error the
    program may run and may seem fine
  • However, one or more errors in the programmers
    logic cause the result will be incorrect!
  • Luckily, in this case the problem is easy to
    correct
  • How?

12
while loop
  • The while loop is also intuitive
  • while (booleanexpression)
  • ltloop bodygt
  • where ltloop bodygt can be any Java statement or
    block
  • Logic of while loop
  • Evaluate (booleanexpression)
  • If result is true, execute ltloop bodygt, otherwise
    skip to next statement after loop
  • Repeat
  • while loop is called an entry loop, because a
    condition must be met to get IN to the loop body
  • Implications of this?

13
Example
  • Lets now use if and while in a simple program
  • User will enter some scores and the program will
    calculate the average
  • Lets do this together, trying to come up with a
    good solution
  • Consider some questions / issues
  • What is the acceptable range for the scores?
  • What do we do if a score is unacceptable?
  • How many scores are there?
  • Do we even know this in advance?
  • What to do if we do not know this in advance?

14
Example
  • Are there any special cases that we need to
    consider?
  • What variables will we need to use?
  • And what will be their types?
  • Once we have a solution, lets look at two
    possible solutions
  • ex5a.java and ex5b.java
  • Note that for many programming problems, there
    are MANY possible solutions

15
do/while Loop
  • Similar to a while loop
  • do
  • ltloop bodygt
  • while (booleanexpression)
  • Logic of the loop
  • First run the loop body once, executing each
    statement
  • Evaluate (booleanexpression)
  • If the expression is true, repeat, otherwise
    continue on in the program
  • The ltloop bodygt is executed
  • The difference
  • A while loop is generally executed zero or more
    times
  • A do/while loop is executed one or more times
  • Which to use depends on your solution
  • Generally, you can augment your program to use
    either

16
for loop
  • The for loop is more complicated
  • Its obvious use is as a counting loop
  • Goes through a specified number of iterations
  • for (int i 0 i lt max i)
  • // will iterate max times
  • However it is much more general than that
  • for (init_expr go_expr inc_expr)
  • // loop body

17
for loop
  • init_expr
  • Any legal Java statement expression
  • Evaluated one time, when the loop is FIRST
    executed
  • go_expr
  • Java Boolean expression
  • Evaluated PRIOR to each execution of the for loop
    body
  • If true, body is executed
  • If false, loop terminates
  • inc_expr
  • Any legal Java statement expression
  • Evaluated AFTER each execution of the for loop
    body
  • These expressions make the for loop extremely
    flexible

18
for loop
  • Try some examples
  • For loop to sum the numbers from N to M
  • N (N1) (M-1) M
  • For loop to output powers of 2 less than or equal
    to K
  • In effect we can use a for loop as if it were a
    while loop if wed like
  • However, it is more readable and less prone to
    logic errors if you use it as a counting loop
  • Lets look at the programs from Example 5, but
    now with a for loop ex5c.java and ex5d.java

19
for loop
  • In Java 5.0, there is an additional, new version
    of the for loop
  • for (type var iterator_obj)
  • ltloop bodygt
  • This version is called the "foreach" loop
  • In a lot of scripting languages such as Perl and
    PHP, so it was adopted into Java
  • However, to use it we need to understand
    something about objects and iterators
  • We will come back and talk about this when we
    come to Object Oriented Programming

20
switch statement
  • We know that if can be used in multiple
    alternative form
  • If we nest statements
  • Sometimes choices are simple, integral values
  • In these cases, it is easier and more efficient
    to use a more specialized statement to choose
  • This is where switch comes in handy
  • However it is kind of wacky so be careful to use
    it correctly!

21
switch statement
  • switch (int_expr)
  • case constant_expr
  • case constant_expr
  • default // this is optional
  • int_expr is initially evaluated
  • constant_expr are tested against int_expr from
    top to bottom
  • First one to match determines where execution
    within the switch body BEGINS
  • However, execution will proceed from there to the
    END of the block

22
switch statement
  • If we want the execution of the different cases
    to be exclusive of each other, we need to stop
    execution prior to the next case
  • We can do this using the break statement
  • Switch is actually passed down to Java from C
    it doesnt really fit too well with the spirit of
    the Java language, but it is there and can be
    used
  • Lets look at an example using switch
  • Program to rate movies
  • User enters a star value from 1-4 and the
    program comments back on the movie quality
  • See ex6.java

23
Methods and Method Calls
  • If programs are short
  • We can write the code as one contiguous segment
  • The logic is probably simple
  • There are not too many variables
  • Not too likely to make a lot of errors
  • As programs get longer
  • Programming in a single segment gets more and
    more difficult
  • Logic is more complex
  • Many variables / expressions / control statements

24
Methods and Method Calls
  • Chances of bugs entering code is higher
  • Isolating and fixing is also harder
  • If multiple people are working on the program, it
    is difficult to break up if written as one
    segment
  • If parts need to be modified or added, it is
    difficult with one large segment
  • If similar actions are taken in various parts of
    the program, it is inefficient to code them all
    separately
  • And can also introduce errors
  • Ex Draw a rectangle somewhere in a window
  • Most of these problems can be solved by breaking
    our program into smaller segments

25
Methods and Method Calls
  • Method (or function or subprogram)
  • A segment of code that is logically separate from
    the rest of the program
  • When invoked (i.e. called) control jumps from
    main to the method and it executes
  • Usually with parameters (arguments)
  • When it is finished, control reverts to the next
    statement after the method call

26
Functional Abstraction
  • Methods provide us with functional (or
    procedural) abstraction
  • We do not need to know all of the implementation
    details of the methods in order to use them
  • We simply need to know
  • What arguments (parameters) we must provide
  • What the effect of the method is (i.e. what does
    it do?)
  • The actual implementation could be done in
    several different ways
  • Ex Predefined method sort(Object a)
  • There are many ways to sort!

27
Functional Abstraction
  • Compare this with data abstraction that we
    mentioned previously (and will discuss again)
  • Both are closely related
  • Functional abstraction is actually part of data
    abstraction
  • Recall that data abstraction relates to both the
    structure and operations involved in a new data
    type
  • We don't need to know the implementation details
    of either the structure or the operations to use
    a type
  • The operations are the part that provide
    functional abstraction
  • However, we can actually have functional
    abstraction without data abstraction
  • Older languages had this prior to OOP

28
Return Value vs. Void
  • Java methods have two primary uses
  • To act as a function, returning a result to the
    calling code
  • In Java these methods are declared with return
    types, and are called within an assignment or
    expression
  • Ex X inScan.nextDouble()
  • Y (Math.sqrt(X))/2
  • To act as a subroutine or procedure, executing
    code but not explicitly returning a result
  • In Java these methods are declared to be void,
    and are called as separate stand-alone statements
  • Ex System.out.println(Wacky)
  • Arrays.sort(myData)

29
Predefined Methods
  • There are MANY predefined methods in Java
  • The Java API shows them all
  • These are often called in the following way
  • ClassName.methodName(param_list)
  • Where ClassName is the class in which the method
    is defined
  • Where methodName is the name of the method
  • Where param_list is a list of 0 or more variables
    or expressions that are passed to the method
  • Ex Y Math.sqrt(X)
  • These are called STATIC methods or CLASS methods
  • They are associated with a class, not with an
    object

30
Predefined Methods
  • Some are also called in the following way
  • ClassName.ObjectName.methodName(param_list)
  • Where ObjectName is the name of a static,
    predefined object that contains the method
  • Ex System.out.println(Hello There)
  • System is a predefined class
  • out is a predefined PrintStream object within
    System
  • println is a method within PrintStream
  • These are instance methods associated with an
    object we will discuss these soon
  • For now we will concentrate on static methods

31
Writing Static Methods
  • What if we need to use a method that is not
    predefined?
  • We will have to write it ourselves
  • Syntax
  • public static void methodName(param_list)
  • // method body
  • public static retval methodName(param_list)
  • // method body
  • Where retval is some Java type
  • When method is not void, there MUST be a return
    statement

32
Writing Static Methods
  • So what about the param_list?
  • It is a way in which we pass values into our
    methods
  • This enables methods to process different
    information at different points in the program
  • Makes them more flexible
  • In the method definition
  • List of type identifier pairs, separated by
    commas
  • Called formal parameters, or parameters
  • In the method call
  • List of variables or expressions that match 1-1
    with the parameters in the definition
  • Called actual parameters, or arguments

33
Writing Static Methods
  • Ex
  • public static double area(double radius)
  • double ans Math.PI radius radius
  • return ans
  • double rad 2.0
  • double theArea area(rad)
  • Note If method is called in same class in which
    it was defined, we dont need to use the class
    name in the call

parameter argument
34
Parameters
  • Parameters in Java are passed by value
  • The parameter is a copy of the evaluation of the
    argument
  • Any changes to the parameter do not affect the
    argument

answer calculated
method completed
answer returned
area method
Main Class
value passed from arg. to parameter
radius
rad
2.0
2.0
ans
12.566
result returned to main
theArea
12.566
double ans Math.PI radius radius
double theArea area(rad)
main calls area method
return ans
35
More on Parameters
  • Effect of value parameters
  • Arguments passed into a method cannot be changed
    within the method, either intentionally or
    accidentally
  • Good result Prevents accidental side-effects
    from methods
  • Bad result What if we want the arguments to be
    changed?
  • Ex swap(A, B)
  • Method swaps the values in A and B
  • But with value parameters will be a no-op
  • We can get around this issue when we get into
    object-oriented programming

36
Local variables and scope
  • Variables declared within a method are local to
    that method
  • They exist only within the context of the method
  • This includes parameters as well
  • Think of a parameter as a local variable that is
    initialized in the method call
  • We say the scope of these variables is the point
    in the method that they are declared up to the
    end of the method

37
Local variables and scope
  • However, Java variables can also be declared
    within blocks inside of methods
  • In this case the scope is the point of the
    declaration until the end of that block
  • Show on board
  • Be careful that you declare your variables in the
    correct block

38
Local variables and scope
  • Note that either way, these variables cannot be
    shared across methods
  • We can still get data from one method to another
  • How?
  • To share variables across methods, we need to use
    object-oriented programming
  • We will see this soon!

39
Arrays
  • So far (for the most part) we have stored data in
    a 11 fashion
  • 1 variable 1 value (or object)
  • This works fine if we know exactly how many
    values we will need to store, and if there are
    few of them
  • However, consider the following scenario
  • We want to input the test scores of a given
    number of students, then 1) find the maximum, 2)
    minimum, 3) average and 4) list them in sorted
    order

40
Arrays
  • We can do the first three things using only a few
    variables
  • Read in current score
  • Add it to the sum
  • If it is less than the minimum score, make it the
    minimum score
  • If it is greater than the maximum score, make it
    the maximum score
  • Repeat until all scores have been read
  • Divide sum by number of scores to get average
  • However, what about listing them in sorted order?

41
Arrays
  • We cant know the final order until all scores
    have been read
  • Last value could be smallest, largest or anywhere
    in between
  • Thus, we need to store all of the values as they
    are being read in, THEN sort them and print them
    out
  • To do this we need a good way to store an
    arbitrary number of values, without requiring the
    same number of variables
  • This is a good example of where an array is
    necessary

42
Java Arrays
  • Java Arrays
  • In Java, arrays are objects, with certain
    properties
  • Like other reference types
  • Simply put, an array is logically a single
    variable name that allows access to multiple
    variable locations
  • In Java, the locations also must be contiguous
    and homogeneous
  • Each directly follows the previous in memory
  • All values stored are of the same type

43
Java Arrays
  • Syntax
  • For now, consider only PRIMITIVE TYPES
  • We create a Java array in 2 steps
  • prim_type var_name
  • where prim_type is any primitive type
  • where var_name is any legal identifier
  • This creates an array variable, but NOT an actual
    array
  • var_name new prim_typearr_size
  • where arr_size is the number of elements that
    will be in the array
  • Indexing in Java always starts at 0

44
Java Arrays
  • Ex
  • int myArray
  • myArray new int20 // size can be a variable
  • // or expression
  • These two steps can be done as one if wed like
  • int myArray new int20
  • Once we have created the array, we now need to
    put values into it
  • Numeric types are initialized to 0
  • Booleans are initialized to false
  • We can change these values via indexing

45
Java Arrays
  • Indexing an array
  • An array variable gives us access to the
    beginning of the array
  • To access an individual location in the array, we
    need to index, using the operator
  • Ex
  • myArray5 250
  • myArray10 2 myArray5
  • myArray11 myArray10 1

46
Java Arrays
  • Iterating through an array
  • We can easily iterate through an entire array
    using a loop (often a for loop)
  • To know when to stop we access the length
    attribute of the array variable
  • Note the syntax
  • for (int i 0 i lt myArray.length i)
  • System.out.print(Value i
    myArrayi)

47
Arrays as Reference Types
  • Java arrays are reference types
  • The array variable is a reference to the actual
    array
  • If I assign the variable (as a whole) it does not
    change the array object
  • But I can alter the contents of the array through
    indexing
  • Ex
  • int A new int5
  • for (int i 0 i lt 5 i)
  • Ai 2i
  • int B A
  • A3 5
  • A new int4
  • A1 3
  • A3 7

A
B
5
48
Arrays as Parameters
  • Recall that all Java parameters are value
  • A copy of the argument is passed to the param
  • Changes to the parameter do not affect the
    argument
  • What about arrays?
  • Still passed by value, but now what is copied is
    the reference (i.e. the variable), NOT the object
  • Thus the effect is that the parameter is another
    reference to the same object that the argument is
    a reference to
  • We cannot change the argument variable in the
    method but we CAN change the array object!

49
Arrays as Parameters
  • Sounds confusing, right?
  • Not so much once you picture it!
  • We will also see an example shortly with ex8.java
  • This allows us to change arrays within methods
  • Ex Read data into an array
  • Ex Remove data from an array
  • Ex Sort an array

50
Searching an Array
  • Often we may want to see if a value is stored in
    an array or not
  • Is this book in the library?
  • Is Joe Schmoe registered for classes?
  • There are many searching algorithms available,
    some simple and some quite sophisticated
  • We will start off simple here with Sequential
    Search

51
Sequential Search
  • Sequential Search
  • Start at the beginning of the array and check
    each item in sequence until the end of the array
    is reached or the item is found
  • Note that we have two conditions here
  • One stops the loop with failure (get to end)
  • The other stops the loop with success (found
    item)
  • We should always consider all possible outcomes
    when developing algorithms
  • Q What kind of loop is best for this?
  • Think about what needs to be done
  • Lets look at an example ex8.java

52
Resizing an array
  • Java array objects can be of any size
  • However once created, they cannot be resized
  • This is fine if we know how many items we will
    need in advance
  • System.out.println("How many integers?")
  • int size inScan.nextInt()
  • int theInts new intsize
  • However, we don't always know this in advance
  • User may have an arbitrary amount of data and
    doesn't know how much until he/she has entered it
  • Amount may vary over time
  • Ex Students in a university

53
Resizing an array
  • So what do we do if we fill our array?
  • Logically, we must "resize" it
  • Physically, we must do the following
  • Create a new, larger array object
  • Copy the data from the old array to the new
  • Assign our reference to the new object
  • This is not difficult syntactically, but it is
    important to realize that this takes time,
    especially if the array is large
  • Clearly we don't want to do this too often
  • A typical approach is to double the size, so we
    have a lot of free locations after the resizing

54
Arrays of Objects
  • We have now seen how to create and use Java
    arrays of primitive types
  • int data // declare variable (reference)
  • data new int20 // create array object
  • data4 77 // index array to access locations
  • How does it differ if we want arrays of objects?
  • The first two steps are the same
  • Declare variable
  • Create array object

55
Arrays of Objects
  • However, remember that objects are accessed by
    reference types
  • Thus, when we create the array, we have an array
    of references, with no objects yet
  • We need to create the objects to store in the
    array separately
  • For example
  • String names
  • names new String5
  • names1 new String(Herb)
  • names3 new String(Madge)
  • names4 new String(Mort)
  • names0 and names2 are still null

56
Lecture 17 Arrays of Objects
  • Note that we have two levels of references here

names
Herb
Madge
Mort
57
2-D Arrays
  • Two-D arrays in Java are actually arrays of
    arrays
  • int A new int48
  • The first index gives us a "row", which is an
    array of items
  • We say this is "row major order"
  • The second index gives us the "column", which is
    the specific item within the row
  • To iterate through all locations we typically use
    nested loops
  • See ex9.java

58
Recursion
  • A Java method can call any other public Java
    method
  • main() is just a method itself, and we have
    called other methods from it
  • Thus, a method should be able to call itself we
    call this a RECURSIVE CALL
  • Since it is a method
  • At first thought this seems odd or even
    impossible why would we want to do this?
  • However, it will be very useful in a lot of
    different programming approaches

59
Recursion
  • Before we look at the programming in detail,
    lets try to get the idea down, using math
  • Some mathematical functions are in fact defined
    recursively
  • Example in text Factorial
  • N! N (N-1)!
  • Note that the function is defined in terms of
    itself, but with an important change
  • The recursive call is smaller in size (N-1)
    than the original call (N)
  • This is vital to recursion being viable
  • Lets trace 4! in this way to see what happens
    (see board)
  • Uh oh!

60
Recursion
  • What we are missing in the previous slide is a
    condition that allows the recursion to stop
  • Every recursive algorithm must have some
    terminating condition, to keep it from recursing
    forever
  • We call this the BASE CASE
  • What is the base case for factorial?
  • This now allows us to complete our algorithm

0! 1
N! N (N-1)! when N gt 0N! 1 when N 0
61
Recursion
  • Three important rules for any recursive
    algorithm
  • There must be some recursive case, in which the
    algorithm calls itself
  • There must be some base case, in which no
    recursive call is made
  • The recursive calls must lead eventually to the
    base case
  • Usually by reducing the problem size in some
    way
  • Dont forget these!

62
More Recursion
  • Lets look at another example
  • Calculating an integer power of another integer
  • MN
  • Dont forget the base case
  • MN
  • The actions we take are slightly different from
    factorial, but the basic idea is similar
  • Trace this on board
  • Note how first call made is last call to complete
  • This is important in the implementation of
    recursion

M MN-1 N gt 0 recursive case
1 N 0 base case
63
Implementing Recursion
  • So how do we implement recursion?
  • Luckily the computer code is very similar to the
    mathematical functions
  • Consider factorial below
  • Note that the recursive call is made within the
    return statement
  • This is fine return is done AFTER call
    completes
  • public static int fact(int N)
  • if (N lt 1)
  • return 1
  • else
  • return (N fact(N-1))

64
Implementing Recursion
  • How does recursion actually work?
  • Each time a method is called, an activation
    record (AR) is allocated for it
  • This consists of memory for the parameters and
    local variables used in the method
  • Each new activation record is placed on the top
    of the run-time stack
  • When a method terminates, its activation record
    is removed from the top of the run-time stack
  • Thus, the first AR placed onto the stack is the
    last one removed

65
Implementing Recursion
N 1 N lt 1? YES return
fact(1)
1
N 2 N lt 1? NO return (2 fact(1))
1
fact(2)
2
N 3 N lt 1? NO return (3 fact(2))
2
fact(3)
6
N 4 N lt 1? NO return (4 fact(3))
6
fact(4)
24
24
66
Recursion vs. Iteration
  • Some recursive algorithms can also be easily
    implemented with loops
  • Both factorial and power can easily be done in
    this way
  • When possible, it is usually better to use
    iteration, since we dont have the overhead of
    the run-time stack (that we just saw on the
    previous slide)
  • Other recursive algorithms are very difficult to
    do any other way (ex Towers of Hanoi)
  • You will see more about recursion in CS 0445
  • For now, lets look at ex10.java

67
Problem Solving with Procedural Programming
  • First, lets review the tools we have at our
    disposal
  • Variables store information for later use in the
    program
  • Statements units of sequential execution
  • Blocks groups of statements
  • Loops (for, while, do)
  • Methods subprograms with their own inputs and
    outputs that perform a specific task

68
Problem Solving with Procedural Programming
  • Given a problem to solve (a program to write)
  • Look for what the program has to do
  • verbs in the problem description
  • Break the program up into a set of well defined
    tasks
  • Each should be separate
  • Modular
  • Design a method, or procedure, to complete each
    task
  • Always at least a main() method
  • Implement each method
  • Integrate them into one program

69
Problem Solving with Procedural Programming
  • Ex
  • Write a program that reads a set of floating
    point values from the user in the range 0, 100,
    computes and prints the average, finds and prints
    the maximum value, finds and prints the minimum
    value, and prints the values in sorted order
  • Whats the program have to do?
  • Read values, check to see if theyre in the
    proper range
  • Compute average
  • Find max
  • Find min
  • Sort
  • Print results
  • We can write a method to do each of these or use
    a predefined method if it exists

70
Problem Solving with Procedural Programming
  • public static double readValues()
  • public static double average(double values)
  • public static double max(double values)
  • public static double min(double values)
  • public static void printValues(double avg, double
    maximum, double minimum, double vals)
  • And then our main method
  • public static void main(String args)
  • double vals readValues()
  • double avg average(vals)
  • double maximum max(vals)
  • double minimum min(vals)
  • printValues(avg, maximum, minimum, vals)
  • Notice that we have no idea how each of our
    methods accomplishes its task at this point, but
    the program still seems to solve the problem
Write a Comment
User Comments (0)
About PowerShow.com