Download Functions - morLAB - University of Toronto

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Functions: The first step in modularity
Prof. Dionne Aleman
MIE250: Fundamentals of object-oriented programming
University of Toronto
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
1/1
Functions
2/1
Java program structure
The .java file
Header files
The class
Function
Function
Function
MIE250: Fundamentals of object-oriented programming (Aleman)
Why functions?
I
Reduce complexity
I
Facilitate understanding and modification
I
Help testing and debugging
I
Promote reusability
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
3/1
Factorial example
1
import java . io .*;
2
3
public class FactorialFn {
4
public static void main ( String [] args ) throws IOException , NumberFormatException {
int n , k , nfact ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in )) ;
do {
System . out . print ( " Enter n (0 to quit ): ") ;
n = Integer . parseInt ( cin . readLine () ) ;
if ( n < 0) {
System . out . println ( " Invalid value . Try again .\ n" );
}
else if ( n > 0) {
nfact = 1;
for ( k = 2; k <= n ; k ++)
nfact *= k ;
System . out . println ( n + " ! = " + nfact + "\ n" ) ;
}
} while ( n != 0) ;
} // end main
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
}
src/FactorialFn.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
4/1
Factorial example
I
Even though calculating n! takes only a few lines, it’s not an
interesting part of the program.
I
Those few lines distract us from the overall program flow (think
human factors).
I
So, let’s move them into a function.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
5/1
Factorial v2: Getting better
1
import java . io .*;
2
3
public class FactorialFnV2 {
4
public static void main ( String [] args ) throws IOException , NumberFormatException {
int n , k , nfact ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in )) ;
do {
System . out . print ( " Enter n (0 to quit ): ") ;
n = Integer . parseInt ( cin . readLine () ) ;
if ( n < 0) {
System . out . println ( " Invalid value . Try again .\ n" );
}
else if ( n > 0) {
System . out . println ( n + " ! = " + factorial ( n) + "\ n" );
}
} while ( n != 0) ;
} // end main
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// calculate factorial
public static int factorial ( int f) {
int nfact = 1;
for ( int k = 2; k <= f ; k ++)
nfact *= k ;
return nfact ;
} // end factorial
20
21
22
23
24
25
26
27
}
src/FactorialFnV2.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
6/1
Some interesting points
I
The function call is in a print statement. Why is that allowed?
I
I
n is passed into the function, but is called f inside the function.
Does that matter?
I
I
I
Because the function returns an int and we can put an int in a
print statement.
Nope. The function call is only passing the value of n to the
function, and the function can assign any name(s) it wants to the
incoming value(s).
Java is exclusively pass-by-value. There is no pass-by-reference!
If f is changed inside the function, will it affect n in the main
function?
I
I
Nope. What happens in functions stays in functions. (exception:
arrays)
“Scope”: Where a variable exists
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
7/1
Functions
8/1
Break it down
1
2
3
4
5
6
public static int factorial ( int f ) {
int nfact = 1;
for ( int k = 2; k <= f ; k ++)
nfact *= k;
return nfact ;
}
src/partial/factorialfn.txt
MIE250: Fundamentals of object-oriented programming (Aleman)
Function construction
1
2
3
4
public static return_type fn_name ( arg_type arg_name [ ,...]) {
// function_body
return ???; // no return statement for void functions
}
I
Return types: Any variable or object type or void
I
void functions don’t return anything
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
9/1
Add absolute value of numbers
1
import java . io .*;
2
3
public class AddAbsValFn {
4
public static void main ( String [] args ) throws IOException ,
NumberFormatException {
double x , y , absSum ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in ));
5
6
7
8
System . out . print ( " Enter two numbers : " ) ;
x = Double . parseDouble ( cin . readLine () ) ;
y = Double . parseDouble ( cin . readLine () ) ;
9
10
11
12
absSum = addAbsVal (x , y ) ;
13
14
System . out . format ( " |%.2 f | + |%.2 f | = %.2 f \ n " , x , y , absSum );
15
16
} // end main
17
18
// return sum of absolute values of two individual numbers
public static double addAbsVal ( double x , double y ) {
return Math . abs (x ) + Math . abs ( y ) ;
}
19
20
21
22
23
}
src/AddAbsValFn.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
10 / 1
Printing the menu
1
import java . io .*;
2
3
public class PrintMenuFn {
4
public static void main ( String [] args ) throws IOException , NumberFormatException {
int choice ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in )) ;
do {
printMenu () ;
choice = Integer . parseInt ( cin . readLine () );
5
6
7
8
9
10
11
if ( choice == 1) {
// do things
}
else if ( choice == 2) {
// do other things
}
else if ( choice != 0) {
System . out . println ( " ERROR : Invalid menu choice !\ n" );
}
} while ( choice != 0) ;
} // end main
12
13
14
15
16
17
18
19
20
21
22
23
// print the menu
public static void printMenu () {
System . out . println ( " MY JAVA PROGRAM ") ;
System . out . println ( " 0 - Quit " );
System . out . println ( " 1 - Option 1" );
System . out . println ( " 2 - Option 2" );
System . out . print ( " \ nEnter choice : " );
}
24
25
26
27
28
29
30
31
32
}
src/PrintMenuFn.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
11 / 1
Functions
12 / 1
Are these statements allowable?
1
2
System . out . println ( printMenu () ) ;
int x = printMenu () ;
MIE250: Fundamentals of object-oriented programming (Aleman)
Odd, prime, or both?
1
public class OddPrime {
2
public static void main ( String [] args ) {
String odd = " " , prime = " " ;
System . out . println ( " No .
Odd Prime " );
System . out . println ( " -----------------") ;
for ( int i = 0; i < 1000; i ++) {
if ( isOdd ( i ) ) odd = " X " ;
else odd = " " ;
3
4
5
6
7
8
9
10
if ( isPrime ( i ) ) prime = " X" ;
else prime = " " ;
11
12
13
System . out . format ( " %3 d %7 s %7 s \n " , i , odd , prime ) ;
} // end loop over integers
} // end main
14
15
16
17
// determine if an integer is prime
public static boolean isPrime ( int n ) {
for ( int i = 2; i <= n -1; i ++) {
if ( n % i == 0)
return false ;
}
return true ;
} // end isPrime
18
19
20
21
22
23
24
25
26
// determine if an integer is odd
public static boolean isOdd ( int n) {
if (( n % 2) == 1) return true ;
else return false ;
} // end isOdd
27
28
29
30
31
32
}
src/OddPrime.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
13 / 1
Ternary operators
Say a lot with very little.
1
variable = ( logical_test ) ? value_if_true : value_if_false ;
Parentheses () are optional, but usually help with clarity.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
14 / 1
Odd, prime, or both? Condensed with ternary operator
1
public class OddPrimeV2 {
2
public static void main ( String [] args ) {
System . out . println ( " No .
Odd Prime " );
System . out . println ( " -----------------") ;
for ( int i = 0; i < 1000; i ++) {
String odd = isOdd ( i ) ? " X " : " " ;
String prime = isPrime ( i ) ? "X " : " ";
System . out . format ( " %3 d %7 s %7 s \n " , i , odd , prime ) ;
} // end loop over integers
} // end main
3
4
5
6
7
8
9
10
11
12
// determine if an integer is prime
public static boolean isPrime ( int n ) {
for ( int i = 2; i <= n -1; i ++) {
if ( n % i == 0)
return false ;
}
return true ;
} // end isPrime
13
14
15
16
17
18
19
20
21
// determine if an integer is odd
public static boolean isOdd ( int n) {
if (( n % 2) == 1) return true ;
else return false ;
} // end isOdd
22
23
24
25
26
27
}
src/OddPrimeV2.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
15 / 1
Transform a numerical score into a letter
1
import java . io .*;
2
3
public class LetterGradeFn {
4
public static void main ( String [] args ) throws IOException ,
NumberFormatException {
double num ;
char letter ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in ));
5
6
7
8
9
System . out . print (" Enter numerical grade : " ) ;
num = Double . parseDouble ( cin . readLine () ) ;
10
11
12
letter = getLetterGrade ( num ) ;
13
14
System . out . format ( " %.2 f -> % s \ n " , num , letter ) ;
15
16
} // end main
17
18
// transform a numerical score into a letter grade
public static char getLetterGrade ( double score ) {
if ( score < 50) return ’F ’;
if ( score < 60) return ’D ’;
if ( score < 70) return ’C ’;
if ( score < 80) return ’B ’;
else return ’A ’;
}
19
20
21
22
23
24
25
26
27
}
src/LetterGradeFn.java
Efficiency
1
2
3
4
5
6
char grade = ’F ’;
if ( score < 50) grade
if ( score < 60) grade
if ( score < 70) grade
if ( score < 80) grade
else grade = ’A ’;
=
=
=
=
’F ’;
’D ’;
’C ’;
’B ’;
7
8
return grade ;
Can you think of a more efficient method of implementing
getLetterGrade()?
I
I will be sad if you say no.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
17 / 1
Alternatives
Alternative 1:
1
2
3
4
5
if ( score >= 90) grade = ’A ’;
else if ( score >= 80 && score < 90) grade = ’B ’;
else if ( score >= 70 && score < 80) grade = ’C ’;
else if ( score >= 60 && score < 70) grade = ’D ’;
else grade = ’F ’;
Alternative 2:
1
2
3
4
5
if ( score >= 90) grade = ’A ’;
else if ( score >= 80) grade = ’B ’;
else if ( score >= 70) grade = ’C ’;
else if ( score >= 60) grade = ’D ’;
else grade = ’F ’;
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
18 / 1
Alternatives
Alternative 3:
1
2
3
4
5
grade = ’F ’;
if ( score >=
if ( score >=
if ( score >=
if ( score >=
60)
70)
80)
90)
grade
grade
grade
grade
=
=
=
=
’D ’;
’C ’;
’B ’;
’A ’;
grade
grade
grade
grade
=
=
=
=
’A ’;
’B ’;
’C ’;
’D ’;
Alternative 4:
1
2
3
4
5
if ( score >=
if ( score >=
if ( score >=
if ( score >=
grade = ’F ’;
90)
80)
70)
60)
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
19 / 1
Which implementations are most efficient?
1
public class PermComb {
2
3
4
5
6
public static void main ( String [] args ) {
System . out . println ( " 10 P 3 = " + permutation (10 , 3) ) ;
System . out . println ( " 10 C 3 = " + combination (10 , 3) ) ;
} // end of main function
7
8
9
10
11
// permutation n P r : n ! / (n - r) !
public static int permutation ( int n , int r ) {
return factorial ( n ) / factorial (n -r ) ;
}
12
13
14
15
16
17
public static int permutationV2 ( int n , int r ) {
int perm = 1;
for ( int i = n - r +1; i <= n ; i ++) perm *= i ;
return perm ;
}
18
19
20
21
22
// combination n C r : n ! / ( r !( n - r) !)
public static int combination ( int n , int r) {
return factorial ( n ) / ( factorial (r ) * factorial (n -r ) );
}
23
24
25
26
27
28
public static int combinationV2 ( int n , int r ) {
int comb = permutationV2 (n , r) ;
for ( int i = 2; i <= r ; i ++) comb /= i ;
return comb ;
}
29
30
31
32
33
34
35
public static int factorial ( int f ) {
int nfact = 1;
for ( int k = 2; k <= f ; k ++) nfact *= k ;
return nfact ;
}
} // end of class
src/PermComb.java
What happens to the vals array in the main function?
1
public class ArrayFn {
2
3
4
5
6
7
8
public static void main ( String [] args ) {
int [] vals = {1 , 3 , 5 , 7 , 9};
printArray ( vals ) ;
squareArray ( vals ) ;
printArray ( vals ) ;
} // end of main function
9
10
11
12
13
14
// square individual array elements
public static void squareArray ( int [] x ) {
for ( int i = 0; i < x . length ; i ++)
x [i] *= x[ i ];
}
15
16
17
18
19
20
21
// print each element in an array
public static void printArray ( int [] x ) {
for ( int i = 0; i < x . length ; i ++)
System . out . println ( i + " . " + x [ i ]) ;
}
} // end of class
src/ArrayFn.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
21 / 1
How about now?
1
public class ArrayFnV2 {
2
public static void main ( String [] args ) {
int [] vals = {1 , 3 , 5 , 7 , 9};
int [] valsSq = squareArray ( vals ) ;
printArray ( vals ) ;
printArray ( valsSq ) ;
} // end of main function
3
4
5
6
7
8
9
// square individual array elements
public static int [] squareArray ( int [] x ) {
int [] sq = new int [ x . length ];
for ( int i = 0; i < x . length ; i ++)
sq [i ] = x[ i ]* x [i ];
return sq ;
}
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// print each element in an array
public static void printArray ( int [] x ) {
for ( int i = 0; i < x . length ; i ++)
System . out . println ( i + " . " + x [ i ]) ;
}
} // end of class
src/ArrayFnV2.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
22 / 1
What is the output of this program?
1
public class Functions {
2
public static void main ( String [] args ) {
int i = 1, j = 2 , k = 3 , m ;
X (i , j );
System . out . println ( ( i ++) + " " + (++ j ) );
m = i + 2;
k = Y(m , j ) ;
System . out . println ( i + " " + j) ;
System . out . println ( Y (j , k +3) ) ;
System . out . println ( i + " " + j + " " + k );
}
3
4
5
6
7
8
9
10
11
12
13
public static void X ( int a , int b) {
int c = b;
b = a;
a = c;
}
14
15
16
17
18
19
public static int Y ( int d , int e ) {
d ++;
e += 2;
return Z (d ) + Z ( e ) ;
}
20
21
22
23
24
25
27
public static int Z ( int f ) {
return f / 2;
28
}
26
29
}
src/Functions.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
23 / 1
Thinking about the user of your functions
1
import java . io .*;
2
3
public class AddAbsValFn {
4
public static void main ( String [] args ) throws IOException , NumberFormatException {
double x , y , absSum ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in )) ;
5
6
7
8
System . out . print ( " Enter two numbers : ") ;
x = Double . parseDouble ( cin . readLine () );
y = Double . parseDouble ( cin . readLine () );
9
10
11
12
absSum = addAbsVal (x , y ) ;
13
14
System . out . format ( " |%.2 f | + |%.2 f| = %.2 f\ n" , x , y , absSum );
15
16
} // end main
17
18
// return sum of absolute values of two individual numbers
public static double addAbsVal ( double x , double y) {
return Math . abs ( x ) + Math . abs ( y );
}
19
20
21
22
23
}
src/AddAbsValFn.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
24 / 1
Overloading: Flexible function use
I
We can only use this function for one thing: adding two doubles
I
But what if we wanted to add several double values? Or ints?
I
I
We could write new functions, e.g., addAbsValDbl3() (add three
doubles), addAbsValInt5() (add five ints)
But this quickly becomes impractical, and difficult for the you (the
programmer) to remember.
Overloading
Function overloading refers to having functions with the same name, but
different arguments.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
25 / 1
Thinking about the user of your functions
1
import java . io .*;
2
3
public class AddAbsValFnV2 {
4
public static void main ( String [] args ) throws IOException , NumberFormatException {
double x , y , absSum ;
BufferedReader cin = new BufferedReader ( new InputStreamReader ( System . in ) ) ;
5
6
7
8
System . out . print ( " Enter two numbers : " );
x = Double . parseDouble ( cin . readLine () ) ;
y = Double . parseDouble ( cin . readLine () ) ;
absSum = addAbsVal (x , y ) ;
System . out . format ( " |%.2 f | + |%.2 f | = %.2 f \n \ n" , x , y , absSum ) ;
9
10
11
12
13
14
System . out . print ( " Enter number of values in array : ") ;
int n = Integer . parseInt ( cin . readLine () ) ;
System . out . print ( " Enter all " + n + " values in array : " );
double [] z = new double [ n ];
for ( int i = 0; i < n ; i ++)
z [ i ] = Double . parseDouble ( cin . readLine () ) ;
absSum = addAbsVal ( z ) ;
System . out . format ( " Sum of absolute values of array elements = %.2 f\ n" , absSum ) ;
15
16
17
18
19
20
21
22
23
} // end main
24
25
// return sum of absolute values of two individual numbers
public static double addAbsVal ( double x , double y ) {
return Math . abs ( x ) + Math . abs ( y) ;
}
26
27
28
29
30
// return sum of absolute values of array elements
public static double addAbsVal ( double [] x ) {
double sum = 0.;
for ( int i = 0; i < x . length ; i ++)
sum += Math . abs ( x [ i ]) ;
return sum ;
}
31
32
33
34
35
36
37
38
}
src/AddAbsValFnV2.java
We can make as many varieties as we want
For example, think about all the different ways we can use
Math.pow(x,y)
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
27 / 1
Lucky Sevens gambling game: Let’s build it from scratch1
Roll two dice. If the values sum to 7, win $4, otherwise lose $1.
1A
completed version is in src/LuckySevens_Complete.java
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
28 / 1
Before programming: Identify inputs and outputs
Inputs
I Starting money
Outputs
I
Number of rolls until you have no more money
I
Peak winnings
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
29 / 1
Before programming: Determine program flow
Increase
cash by $4
yes
yes
Get starting
cash value
from user
Roll dice
Dice value
= 7?
Money
left?
no
Quit
no
Decrease
cash by $1
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
30 / 1
Time to program
Now that we know what we want to do, let’s build the program.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
31 / 1
Simulation: An IE staple
I
What is the average peak winnings as a percentage of starting cash
value?
I
What is the probability of lasting longer than n rolls with a certain
starting cash value?
I
What starting cash value has the best dollars to rolls ratio?
Simulation
Due to uncertain outcomes, we can’t answer most questions like this with
just one run of the game. We need to simulate many games in order to
create a distribution of outcomes that we can analyze.
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
32 / 1
New Lucky Sevens simulation program flow
Increase
cash by $4
yes
Get starting
cash value
from user
Get #
simulations
from user
Set
simulation
counter
n = 0
Roll dice
yes
Dice value
= 7?
Money
left?
no
Quit game
no
Collect
stats
Decrease
cash by $1
Reset stats
Set cash
= starting
cash
Set
n = n+1
no
n =#
simulations?
yes
Quit
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
Do analysis
33 / 1
A skeleton of the program
1
2
3
4
5
public LuckySevensSimulation {
public static void main ( String args []) {
int cash = getStartingCash () ;
int nRolls = 0;
int maxCash = 0;
6
for ( int i = 0; i < 1000; i ++) {
nRolls = play ( cash ) ; // or maybe maxCash = play ( cash );
// collect some stats on nRolls and maxCash ...
}
7
8
9
10
11
// print out all stats results ...
12
}
13
14
// play the Lucky Sevens game
public static int play ( int cash ) { ... }
15
16
17
// get starting cash amount from user
public static int getStartingCash () { ... }
18
19
20
}
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
34 / 1
Bigger issues than just more loops ...
I
We want to collect at least two types of stats from each game:
nRolls and maxCash.
I
But how do we get the play() function to return two values?
I
Answer: We can’t.
Passing around lots of data
There’s no pass-by-reference, so there is only one reasonable option:
Create an object to store the data and then pass the one object around,
or just have the object do all the work. Finally, let’s do some
object-oriented programming!
MIE250: Fundamentals of object-oriented programming (Aleman)
Functions
35 / 1
Related documents