more work with functions

51
More work with functions

Upload: eithne

Post on 12-Jan-2016

21 views

Category:

Documents


0 download

DESCRIPTION

More work with functions. Recall the “diary encoding problem”:. (We shifted letters of the alphabet one position to the left.) So IBM becomes HAL . And Mary becomes Lzqx. Here’s the complete program that writes the encoded information to another file. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: More work with functions

More work with functions

Page 2: More work with functions

Recall the “diary encoding problem”:

• (We shifted letters of the alphabet one position to the left.)

– So IBM becomes HAL.

– And Mary becomes Lzqx.

Page 3: More work with functions

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.PrintWriter;import java.util.Scanner;

class Encode { public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

//perform encoding char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; } out.println( outLine ); //output encoded line }

out.close(); in.close(); }}

Here’s the complete program that writes the encoded information to another file.

Can we make a function out of the encoding part?

That would make our code more readable and modular (in case we want to change the encoding).

Page 4: More work with functions

Java code segment for encoding:char enc;if (ch=='a') { //handle lowercase letters

enc = 'z';} else if (ch>'a' && ch<='z') { //handle lowercase letters

enc = (char)(ch-1);} else if (ch=='A') { //handle uppercase letters

enc = 'Z';} else if (ch>'A' && ch<='Z') { //handle uppercase letters

enc = (char)(ch-1);} else {

enc = ch; //unchanged}

Page 5: More work with functions

Recall the steps to define your own function.

1. Decide on a name for your function.2. Determine what arguments your

function needs to do its job.3. Determine the return type of your

function.4. Code your function.

Page 6: More work with functions

Steps to define your own function.

Step 1. Decide on a name.

encode

Page 7: More work with functions

Steps to define your own function.

Step 2. Determine what arguments your functions needs to do its job.

– What does encode need to do its job?

1. One character to check/translate.char before

Page 8: More work with functions

After steps 1 and 2.

encode ( char before ) {…

}

Step 3. What type of thing does our function return?

Page 9: More work with functions

After steps 1 and 2.

encode ( char before ) {…

}

Step 3. What type of thing does our function return?

the encoded char

Page 10: More work with functions

After steps 1, 2, and 3.

static char encode ( char before ) {…

}

Now all we have to do is fill in the body of our function!

The simplest encoder is one that doesn’t make any change. What should that encoder return?

Page 11: More work with functions

After steps 1, 2, and 3.

static char encode ( char before ) {return before;

}

Now all we have to do is fill in the body of our function.

The simplest encoder is one that doesn’t make any change.

How can we use this simple encoder function?

Page 12: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else if (ch=='A') { //handle uppercase letters enc = 'Z'; } else if (ch>'A' && ch<='Z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; } out.println( outLine ); //output encoded line }….

To use this simple encoder function, we first add it to our class (inside class definition but outside of main).

Page 13: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else if (ch=='A') { //handle uppercase letters enc = 'Z'; } else if (ch>'A' && ch<='Z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; } out.println( outLine ); //output encoded line }….

To use this simple encoder function, we first add it to our class.

The next step is to replace the encoding code in main with a call to our encode function.

Page 14: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else if (ch=='A') { //handle uppercase letters enc = 'Z'; } else if (ch>'A' && ch<='Z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; } out.println( outLine ); //output encoded line }….

To use this simple encoder function, we first add it to our class.

The next step is to replace the encoding code in main with a call to our encode function.

What functions do we already call in main?

Page 15: More work with functions

…class Encode { static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file

Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file

PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time

while ( in.hasNextLine() ) {

String s = in.nextLine(); String outLine = "";

System.out.println( "read: " + s );

for (int i=0; i<s.length(); i++) {

char ch = s.charAt( i ); char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else if (ch=='A') { //handle uppercase letters enc = 'Z'; } else if (ch>'A' && ch<='Z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; }

out.println( outLine ); //output encoded line }….

To use this simple encoder function, we first add it to our class.

The next step is to replace the encoding code in main with a call to our encode function.

We already call these functions in main!

Page 16: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

char enc; if (ch=='a') { enc = 'z'; } else if (ch>'a' && ch<='z') { enc = (char)(ch-1); } else if (ch=='A') { //handle uppercase letters enc = 'Z'; } else if (ch>'A' && ch<='Z') { enc = (char)(ch-1); } else { enc = ch; //unchanged } outLine = outLine + enc; } out.println( outLine ); //output encoded line }….

So we replace all this with what?

Page 17: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) { char ch = s.charAt( i );

char enc = encode( ch ); outLine = outLine + encode( ch ); outLine = outLine + enc; } out.println( outLine ); //output encoded line }….

Both versions are fine.

Page 18: More work with functions

…class Encode {

static char encode ( char before ) { return before; } public static void main ( String args[] ) throws Exception { //open the input file Scanner in = new Scanner( new FileInputStream("diary.txt") ); //open the output file PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") ); //read & write one line at a time while ( in.hasNextLine() ) { String s = in.nextLine(); String outLine = ""; System.out.println( "read: " + s ); for (int i=0; i<s.length(); i++) {

char ch = s.charAt( i ); outLine += encode( s.charAt(i) );outLine = outLine + encode( ch );

} out.println( outLine ); //output encoded line }….

This is OK as well.

Page 19: More work with functions

…class Encode {

static char encode ( char before ) { return before; }….

Now we need to complete the encode function based on our code from before:

char enc;if (ch=='a') {

enc = 'z';} else if (ch>'a' && ch<='z') {

enc = (char)(ch-1);} else if (ch=='A') { //handle uppercase letters

enc = 'Z';} else if (ch>'A' && ch<='Z') {

enc = (char)(ch-1);} else {

enc = ch; //unchanged}

Page 20: More work with functions

…class Encode {

static char encode ( char before ) { return before; }….

Note that ch below is called before w/in the scope of the encode function.

Also for readability, since ch is before, let’s call enc after.

char enc;if (ch=='a') {

enc = 'z';} else if (ch>'a' && ch<='z') {

enc = (char)(ch-1);} else if (ch=='A') { //handle uppercase letters

enc = 'Z';} else if (ch>'A' && ch<='Z') {

enc = (char)(ch-1);} else {

enc = ch; //unchanged}

Page 21: More work with functions

Our completed encode function…class Encode { //encode a given character for our secret code static char encode ( char before ) { char after; if (before=='a') { after = 'z'; } else if (before>'a' && before<='z') { after = (char)(before-1); } else if (before=='A') { //handle uppercase letters after = 'Z'; } else if (before>'A' && before<='Z') { after = (char)(before-1); } else { after = before; //unchanged } return after; }….

Page 22: More work with functions

Our completed encode function…class Encode { //encode a given character for our secret code static char encode ( char before ) { char after = before; //unchanged if (before=='a') { after = 'z'; } else if (before>'a' && before<='z') { after = (char)(before-1); } else if (before=='A') { //handle uppercase letters after = 'Z'; } else if (before>'A' && before<='Z') { after = (char)(before-1); } else { after = before; //unchanged } return after; }….

a slightly different way

Page 23: More work with functions

Our completed encode function…class Encode { //encode a given character for our secret code static char encode ( char before ) {

if (before=='a') { return ‘z‘; } else if (before>'a' && before<='z') { return (char)(before-1); } else if (before=='A') { //handle uppercase letters return 'Z'; } else if (before>'A' && before<='Z') { return (char)(before-1); } return before; //unchanged }….

a slightly different way

Page 24: More work with functions

A FUNCTION THAT APPROXIMATES SINE

Page 25: More work with functions

A function to approximate sine

• From http://en.wikipedia.org/wiki/Trigonometric_function#Series_definitions

Page 26: More work with functions

The sine function (blue) is closely approximated by its Taylor polynomial of degree 7 (pink) for a

full cycle centered on the origin.

Page 27: More work with functions

Let’s write a function to approximate sine

• Use the following polynomial:

Page 28: More work with functions

Recall the steps to define your own function.

1. Decide on a name for your function.2. Determine what arguments your

function needs to do its job.3. Determine the return type of your

function.4. Code your function.

Page 29: More work with functions

Steps 1

1. Decide on a name for your function.

almostSine

Page 30: More work with functions

Steps 2

2. Determine what arguments your function needs to do its job.

almostSine ( double x )

Page 31: More work with functions

Steps 3

3. Determine the return type of your function.

static double almostSine ( double x )

Page 32: More work with functions

Steps 4

4. Code your function.//approx sine w/ a 7th degree polynomialstatic double almostSine ( double x ) {

}

Page 33: More work with functions

Steps 4

4. Code your function.//approx sine w/ a 7th degree polynomialstatic double almostSine ( double x ) {

double x3 = x * x * x;double x5 = ?;double x7 = ?;double y = ?;

return y;}

Note: A loop over the number of terms is more general, but for simplicity we will use only 4 terms.

Page 34: More work with functions

Steps 4

4. Code your function.//approx sine w/ a 7th degree polynomialstatic double almostSine ( double x ) {

double x3 = x * x * x;double x5 = x3 * x * x;double x7 = x5 * x * x;double fact3 = ?;double fact5 = ?;double fact7 = ?;double y = ?;return y;

}

Page 35: More work with functions

Steps 4

4. Code your function.//approx sine w/ a 7th degree polynomialstatic double almostSine ( double x ) {

double x3 = x * x * x;double x5 = x3 * x * x;double x7 = x5 * x * x;double fact3 = 3 * 2;double fact5 = 5 * 4 * fact3;double fact7 = 7 * 6 * fact5;double y = ?;return y;

}

Page 36: More work with functions

Steps 4

4. Code your function.//approx sine w/ a 7th degree polynomialstatic double almostSine ( double x ) {

double x3 = x * x * x;double x5 = x3 * x * x;double x7 = x5 * x * x;double fact3 = 3 * 2;double fact5 = 5 * 4 * fact3;double fact7 = 7 * 6 * fact5;double y = x – x3/fact3 + x5/fact5 – x7/fact7;return y;

}

Page 37: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } How can we test our new function, almostSine?

Page 38: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } public static void main ( String args[] ) {

for (double d=-2*Math.PI; d<=2*Math.PI; d+=Math.PI/2) { System.out.println( d + "\t" + Math.sin(d) ); } }}

What does this print out?

How can we modify it to print out the values of our new function as well?

Page 39: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } public static void main ( String args[] ) {

for (double d=-2*Math.PI; d<=2*Math.PI; d+=Math.PI/2) { System.out.println( d + "\t" + Math.sin(d)

+ "\t" + almostSine(d) ); } }}

Page 40: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } public static void main ( String args[] ) {

for (double d=-2*Math.PI; d<=2*Math.PI; d+=Math.PI/2) { System.out.println( d + "\t" + Math.sin(d)

+ "\t" + almostSine(d) ); } }}

-12.566370614359172 4.898587196589413E-16 7525.149318866292-10.995574287564276 1.0 2726.801987700507-9.42477796076938 -3.6739403974420594E-16 821.0051310349569-7.853981633974483 -1.0 189.61411535680668-6.283185307179586 2.4492935982947064E-16 30.1591274102065-4.71238898038469 1.0 3.602329768407337-3.141592653589793 -1.2246467991473532E-16 0.0752206159036235-1.5707963267948966 -1.0 -0.99984310139949870.0 0.0 0.01.5707963267948966 1.0 0.99984310139949873.141592653589793 1.2246467991473532E-16 -0.07522061590362354.71238898038469 -1.0 -3.6023297684073376.283185307179586 -2.4492935982947064E-16 -30.15912741020657.853981633974483 1.0 -189.614115356806689.42477796076938 3.6739403974420594E-16 -821.005131034956910.995574287564276 -1.0 -2726.80198770050712.566370614359172 -4.898587196589413E-16 -7525.149318866292

Can we format this better?

Page 41: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } public static void main ( String args[] ) {

for (double d=-Math.PI; d<=2*Math.PI; d+=Math.PI/2) { System.out.printf( "%8.2f %8.2f %8.2f \n", d, Math.sin(d), almostSine(d) ); } }}

-12.57 0.00 7525.15 -11.00 1.00 2726.80 -9.42 -0.00 821.01 -7.85 -1.00 189.61 -6.28 0.00 30.16 -4.71 1.00 3.60 -3.14 -0.00 0.08 -1.57 -1.00 -1.00 0.00 0.00 0.00 1.57 1.00 1.00 3.14 0.00 -0.08 4.71 -1.00 -3.60 6.28 -0.00 -30.16 7.85 1.00 -189.61 9.42 0.00 -821.01 11.00 -1.00 -2726.80 12.57 -0.00 -7525.15

It’s nice and readable now.

And the values are good from –Pi to +Pi.

But something happens here…

Page 42: More work with functions

The sine function (blue) is closely approximated by its Taylor polynomial of degree 7 (pink) for a

full cycle centered on the origin.

Note what happens to our approximation outside of [-Pi,+Pi].

Page 43: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.

• Outside of this range, we need to map each 2Pi interval to start at –Pi.

• Then we could use almostSine(f(x)) and get a reasonable value.

Page 44: More work with functions

class MySine {

//approx sine w/ a 7th degree polynomial static double almostSine ( double x ) { double x3 = x * x * x; double x5 = x3 * x * x; double x7 = x5 * x * x; double fact3 = 3 * 2; double fact5 = 5 * 4 * fact3; double fact7 = 7 * 6 * fact5; double y = x - x3/fact3 + x5/fact5 - x7/fact7; return y; } public static void main ( String args[] ) {

for (double d=-Math.PI; d<=2*Math.PI; d+=Math.PI/2) { System.out.printf( "%8.2f %8.2f %8.2f \n",

d, Math.sin(d), almostSine(f(d)) );

} }}

Page 45: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.

• Outside of this range, we need to map each 2Pi interval to start at –Pi.

• So let’s start with the identity function:static double f ( double x ) {

return x;}

Page 46: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.• Outside of this range, we need to map each 2Pi interval to start at –Pi.

static double f ( double x ) {//no change if in [-Pi..+Pi]if (-Math.PI<=x && x<=Math.PI) return x;

return x;}

How can we map each 2Pi interval to start at –Pi?(Did we use any arithmetic operator before that does this – random numbers and rolling

dice?)

Page 47: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.• Outside of this range, we need to map each 2Pi interval to start at –Pi.

static double f ( double x ) {//no change if in [-Pi..+Pi]if (-Math.PI<=x && x<=Math.PI) return x;x %= 2*Math.PI;

return x;}

If this yields a number in [-Pi..+Pi], then this is fine.

Page 48: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.• Outside of this range, we need to map each 2Pi interval to start at –Pi.

static double f ( double x ) {//no change if in [-Pi..+Pi]if (-Math.PI<=x && x<=Math.PI) return x;x %= 2*Math.PI;if (-Math.PI<=x && x<=Math.PI) return x;

return x;}

If this yields a number in [-Pi..+Pi], then this is fine.Otherwise, we need to shift the result.

Page 49: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.• Outside of this range, we need to map each 2Pi interval to start at –Pi.

static double f ( double x ) {//no change if in [-Pi..+Pi]if (-Math.PI<=x && x<=Math.PI) return x;x %= 2*Math.PI;if (-Math.PI<=x && x<=Math.PI) return x;if (x>0) return x - 2*Math.PI;return x;

}

If this yields a number in [-Pi..+Pi], then this is fine.Otherwise, we need to shift the result.

Page 50: More work with functions

• So we need another function, f(x), which between –Pi and +Pi is x.• Outside of this range, we need to map each 2Pi interval to start at –Pi.

static double f ( double x ) {//no change if in [-Pi..+Pi]if (-Math.PI<=x && x<=Math.PI) return x;x %= 2*Math.PI;if (-Math.PI<=x && x<=Math.PI) return x;if (x>0) return x - 2*Math.PI;return x + 2*Math.PI;

}

If this yields a number in [-Pi..+Pi], then this is fine.Otherwise, we need to shift the result.

Page 51: More work with functions

PHEW!

-12.57 0.00 0.00 -11.78 0.71 0.71 -11.00 1.00 1.00 -10.21 0.71 0.70 -9.42 -0.00 0.08 -8.64 -0.71 -0.70 -7.85 -1.00 -1.00 -7.07 -0.71 -0.71 -6.28 0.00 0.00 -5.50 0.71 0.71 -4.71 1.00 1.00 -3.93 0.71 0.70 -3.14 -0.00 0.08 -2.36 -0.71 -0.70 -1.57 -1.00 -1.00 -0.79 -0.71 -0.71 0.00 0.00 0.00 0.79 0.71 0.71 1.57 1.00 1.00 2.36 0.71 0.70 3.14 -0.00 0.08 3.93 -0.71 -0.70 4.71 -1.00 -1.00 5.50 -0.71 -0.71 6.28 0.00 0.00 7.07 0.71 0.71 7.85 1.00 1.00 8.64 0.71 0.70 9.42 -0.00 0.08 10.21 -0.71 -0.70 11.00 -1.00 -1.00 11.78 -0.71 -0.71