Summary

These are notes on Python functions, covering function definitions, arguments, and return values. It is a programming reference for Python.

Full Transcript

INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries 2.1–2.2 https://introcs.cs.princeton.edu/pytho...

INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries 2.1–2.2 https://introcs.cs.princeton.edu/python Slides ported to Python by James Pope Last updated on 2023/10/20 08:45 INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries Basic concepts Case study: Digital audio Application: Gaussian distribution Modular programming and libraries Context: basic building blocks for programming any program you might want to write objects functions and libraries graphics, sound, and image I/O array s conditionals and conditionals and loops loops Mat text h I/O primitive data assignment types statements 3 Functions Python function Takes zero or more input arguments. Returns zero or one output value. May cause side effects (e.g., output to standard draw). function f Python functions are more general than mathematical functions Applications Scientists use mathematical functions to calculate formulas. Programmers use functions to build modular programs. You use functions for both. Examples seen so far Built-in functions: abs(), len(), int(). Our I/O libraries: stdio.write(), stddraw.line(), stdaudio.play(). User-defined functions: main(). 4 Function Definition To implement a function Create a function name. Consider type and declare name of parameter variables. Consider type and specify return value. Implement function body. Finish with return statement. 5 Function Calls To call a function Call is the function name followed by arguments, separated by commas, enclosed in parenthesis. When function finishes, the return value effectively takes the place of the function call. def main(): for i in range(1, len(sys.argv)): arg = int(sys.argv[i]) value = harmonic( arg ) stdio.writeln(value) if __name__ == '__main__': main() 6 Control Flow - First iteration of the global for loop Processes the import statements making the features defined in modules available. Processes the definition of the harmonic() function but does not execute the function. (only when it is called). Executes the first statement in the global code until value =... at which point transfers control to the harmonic() function. Initializes the “parameter” variable n to 1 and the “local” variable total to 0.0. Executes the for loop within harmonic(), which terminates after one iteration with total equal to 1.0. Executes the return statement at the end of the definition of harmonic(), jumps back to the calling statement continuing from where it left off, but now with the expression harmonic(arg) replaced by 1.0. 7 Scope Def. The scope of a variable is the code that can refer to it by name. In a Python program, a variable’s scope is the code following its import stdio declaration, in the same block. import stdarray cannot refer i in this code import sys There is a global scope in the scope of c and eps def sqrt( c, eps ): program such that all functions in if (c < 0.0): return math.nan scope of t the program can access. t = c while (abs(t - c/t) > eps * t): Should only use global scope for t = (c/t + t) / 2.0 return t constant variables and name in all caps (e.g. EPS). def main(): a = stdarray.create1D( len(sys.argv)-1, 0.0 ) for i in range( len(a) ): a[i] = float(sys.argv[i+1]) two different variables named i each with scope limited to a single for loop for i in range( len(a) ): stdio.writeln( sqrt(a[i], 1e-3) ) cannot refer to Best practice. Declare variables == if __name__ so as to limit their main() '__main__': scope. c, eps, or t in this code 8 Flow of control import stdio import stdarray Summary of flow control for a function call import sys Control transfers to the function code. def sqrt( c, eps ): Argument variables are declared and if (c < 0.0): return math.nan t = c initialized with the given values. while (abs(t - c/t) > eps * t): t = (c/t + t) / 2.0 Function code is executed. return t Control transfers back to the calling code def main(): (with return value assigned in place of the a = stdarray.create1D( len(sys.argv)-1, 0.0 ) for i in range( len(a) ): function name in the calling code). a[i] = float(sys.argv[i+1]) for i in range( len(a) ): stdio.writeln( sqrt(a[i], 1e-3) ) Note. OS calls python that then executes the if __name__ == '__main__': main() global code in the python file. The bottom if statement then calls the main() function. 9 Function call flow of control trace import stdio c t import stdarray c t import sys 3.0 3.0 2.0 2.0 2.0 1.5 def sqrt( c, eps ): 1.75 if (c < 0.0): return math.nan c t1.417 t = c 1.732 1.0 1.414 1.0 while (abs(t - c/t) > eps * t): t = (c/t + t) / 2.0 return t i a[i] x i a[i] def main(): 0 1.0 1.000 a = stdarray.create1D( len(sys.argv)-1, 0.0 ) 0 1.0 1 2.0 1.414 1 2.0 for i in range( len(a) ): 2 3.0 1.732 2 3.0 a[i] = float(sys.argv[i+1]) 3 for i in range( len(a) ): % python newton.py 1 2 3 stdio.writeln( sqrt(a[i], 1e-3) ) 1.0 1.4142156862745097 if __name__ == '__main__': main() 1.7321428571428572 10 Pop quiz 1a on functions Q. What happens when you compile and run the following code? import stdio import sys def cube(i): j = i * i * i return j def main(): N = int(sys.argv) for i in range(1, N+1): stdio.writeln(str(i) + " " + str(cube(i))) if __name__ == '__main__': main() 11 Pop quiz 1a on functions Q. What happens when you compile and run the following code? import stdio import sys A. Takes N from the command line, then prints cubes of integers from 1 to N def cube(i): j = i * i * i return j % python pqfunctions1a.py 6 1 1 def main(): 2 8 N = int(sys.argv) 3 27 for i in range(1, N+1): stdio.writeln(str(i) + " " + str(cube(i))) 4 64 5 125 if __name__ == '__main__': main() 6 216 12 Pop quiz 1b on functions Q. What happens when you compile and run the following code? import stdio import sys def cube(i): i = i * i * i return i def main(): N = int(sys.argv) for i in range(1, N+1): stdio.writeln(str(i) + " " + str(cube(i))) if __name__ == '__main__': main() 13 Pop quiz 1b on functions Q. What happens when you compile and run the following code? A. Same correct output. The parameter import stdio import sys variable i is reassigned to cube result. BUT changing parameter variables is confusing def cube(i): and bad style. i = i * i * i return i % python pqfunctions1a.py 6 1 1 def main(): 2 8 N = int(sys.argv) 3 27 for i in range(1, N+1): stdio.writeln(str(i) + " " + 4 64 str(cube(i))) 5 125 6 216 if __name__ == '__main__': main() 14 Pop quiz 1c on functions Q. What happens when you compile and run the following code? import stdio import sys def cube(i): j = i * i * i def main(): N = int(sys.argv) for i in range(1, N+1): stdio.writeln(str(i) + " " + str(cube(i))) if __name__ == '__main__': main() 15 Pop quiz 1c on functions Q. What happens when you compile and run the following code? import stdio A. Logic error. Need return statement, import sys otherwise function automatically returns None. def cube(i): j = i * i * i % python pqfunctions1a.py 6 def main(): 1 None N = int(sys.argv) for i in range(1, N+1): 2 None stdio.writeln(str(i) + " " + 3 None str(cube(i))) 4 None 5 None if __name__ == '__main__': main() 6 None 16 Pop quiz 1d on functions Q. What happens when you compile and run the following code? import stdio import sys def cube(i): return i * i * i def main(): N = int(sys.argv) for i in range(1, N+1): stdio.writeln(str(i) + " " + str(cube(i))) if __name__ == '__main__': main() 17 Pop quiz 1d on functions Q. What happens when you compile and run the following code? import stdio A. Works fine. Preferred (compact) code. import sys def cube(i): % python pqfunctions1a.py return i * i * i 6 1 1 def main(): 2 8 N = int(sys.argv) 3 27 for i in range(1, N+1): 4 64 stdio.writeln(str(i) + " " + str(cube(i))) 5 125 if __name__ == '__main__': main() 6 216 18 INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO Image sources http://upload.wikimedia.org/wikipedia/commons/b/ba/Working_Together_Teamwork_Puzzle_Concept.jpg http://pixabay.com/en/ball-puzzle-pieces-of-the-puzzle-72374/ http://upload.wikimedia.org/wikipedia/commons/e/ef/Ben_Jigsaw_Puzzle_Puzzle_Puzzle.png http://en.wikipedia.org/wiki/Function_(mathematics)#mediaviewer/File:Function_machine2.svg INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries Basic concepts Case study: Digital audio Application: Gaussian distribution Modular programming Crash course in sound Sound is the perception of the vibration of molecules. A musical tone is a steady periodic sound. A pure tone is a sinusoidal waveform. pitch i frequency (440*2i/12) sinusodial waveform A 0 440 Western musical scale A♯ / B♭ 1 466,16 Concert A is 440 Hz. B 2 493,88 C 3 523,25 12 notes, logarithmic scale. C♯ / D♭ 4 554,37 D 5 587,33 D♯ / E♭ 6 622,25 E 7 659,26 F 8 698,46 F♯ / G♭ 9 739,99 G 10 783,99 G♯ / A♭ 11 830,61 A 12 880 21 Digital audio same as when plotting a To represent a wave, sample at regular intervals and save the values in an array. function samples/sec samples sampled waveform 1/40 second of concert A 5 512 137 11 025 275 22 050 551 CD standard 44 100 1102 Bottom line. You can write programs to manipulate sound (arrays of float values). 22 stdaudio library Developed for this course, also broadly useful Play a sound wave (array of double values) on your computer’s audio output. Convert to and from standard.wav file format. public class stdaudio void playFile(file) play the given.wav file void playSamples(float[] a) play the given sound wave API void playSample(s) play the sample for 1/44100 second void save(file, a) save array a to.wav file float[] read(file) read array from a.wav file return type usually in signature but not in Python Enables you to hear the results of your programs that manipulate sound. 23 "Hello, World" for stdaudio playthatnote.py import stdio import stdarray import stdaudio import math i import sys def tone( hz, duration ): N = int(44100.0 * duration) a = stdarray.create1D( N+1, 0.0 ) for i in range(0, N+1): a[i] = math.sin(2.0 * math.pi * i * hz / 44100.0) % python playthatnote.py 440.0 3.0 return a % python playthatnote.py 880.0 3.0 def main(): % python playthatnote.py 220.0 3.0 hz = float(sys.argv) duration = float(sys.argv) % python playthatnote.py 494.0 3.0 a = tone(hz, duration) stdaudio.playSamples(a) 24 Play that tune Read a list of tones and durations from standard input to play a tune. % more < elise.txt import stdio 7.125 import stdaudio 6.125 import playthatnote 7.125 6.125 import math 7.125 import sys playthattune.py 2.125 5.125 def main(): 3.125 ABCDEFGA 0.25 tempo = float( sys.argv )... while (not stdio.isEmpty()): % python playthattune.py 2.0 < elise.txt pitch = stdio.readInt() duration = stdio.readFloat() * tempo 76 7672530 hz = 440.0 * math.pow(2, pitch / 12.0) a = playthatnote.tone(hz, duration) stdaudio.playSamples(a) % python playthattune.py 1.0 < elise.txt if __name__ == '__main__': main() 25 Pop quiz 2 on functions Q. What sound does the following program produce? import stdaudio import stdarray import stdrandom def main(): N = (int) (44100 * 11); a = stdarray.create1D(N+1, 0.0) for i in range(N+1): a[i] = stdrandom.uniform() # float between [0.0,1.0) stdaudio.playSamples(a) if __name__ == '__main__': main() pqfunctions2.py 26 Pop quiz 2 on functions Q. What sound does the following program produce? import stdaudio import stdarray import stdrandom def main(): N = (int) (44100 * 11); a = stdarray.create1D(N+1, 0.0) for i in range(N+1): a[i] = stdrandom.uniform() # float between [0.0,1.0) A. 11 seconds of pure noise. stdaudio.playSamples(a) % python pqfunctions2.py if __name__ == '__main__': main() pqfunctions2.py 27 Play that chord Produce chords by averaging waveforms. a a[i] def superpose(a, b, aWeight, bWeight): c = stdarray.create1D(len(a), 0.0) b[i] for i in range(len(a)): b c[i] = a[i]*aWeight + b[i]*bWeight return c c a[i]/2.0 + b[i]/2.0 all values stay between equally weighted 0 and 1 i 28 Play that chord implementation import stdaudio import stdarray import math import playthatnote import sys def superpose(a, b, aWeight, bWeight): SEE PREVIOUS SLIDE def chord( pitch1, pitch2, d ): ABCDEFGA hz1 = 440.0 * math.pow(2, pitch1 / 12.0) hz2 = 440.0 * math.pow(2, pitch2 / 12.0) a = playthatnote.tone(hz1, d) b = playthatnote.tone(hz2, d) % python playthatchord.py 0 3 5.0 return superpose(a, b, 0.5, 0.5) def main(): % python playthatchord.py 0 12 5.0 pitch1 = int(sys.argv) pitch2 = int(sys.argv) duration = float(sys.argv) a = chord(pitch1, pitch2, duration) playthatnote.py stdaudio.playSamples(a) 29 frequency Play that tune (deluxe version) Add harmonics to PlayThatTune to produce a more realistic sound. half Function to add harmonics to a tone lo frequency def note(pitch, t): CONCERT_A_HZ = 440.0 double frequency hi NOTES_ON_SCALE = 12.0 hz = CONCERT_A_HZ * (2.0 ** (pitch / NOTES_ON_SCALE)) a = tone(hz, t) both harmonics harmonic hi = tone(2*hz, t) lo = tone(hz/2, t) h = superpose(hi, lo,.5,.5) pure pitch a return superpose(a, h,.5,.5) result % python playthattunedeluxe.py < elise.txt Program 2.1.4 in text (with tempo added) superpose(a, harmonic) 30 Digital audio (summary) % python playthattunedeluxe.py < entertainer.txt Bottom line. You can write programs to manipulate sound. This lecture: Case study of the utility of functions. Upcoming assignment: Fun with musical tones. 31 INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO Image sources http://commons.wikimedia.org/wiki/File:1405_Sound_Waves_and_the_Ear.jpg http://en.wikipedia.org/wiki/The_Entertainer_(rag)#mediaviewer/File:EntertainerJoplinCover.JPEG http://cantorion.org/music/497/The-Entertainer-Original-version INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries Basic concepts Case study: Digital audio Application: Gaussian distribution Modular programming Gaussian distribution Gaussian distribution. A mathematical model used successfully for centuries. "Bell curve" fits experimental observations in many contexts. −4 −3 −2 −1 0 1 2 3 4 601 1019 1437 34 Gaussian distribution in the wild German money Polystyrene particles in glycerol Cytochrome oxidase patches in macaque primary visual cortex Calibration of optical tweezers Polarized W bosons from top-quark decay Laser beam propagation 35 Defining a library of functions Q. Is the Gaussian pdf Φ implemented in Python's math library? A. No. Q. Why not? A. Maybe because it is so easy for you to do it yourself.... def phi(x): return math.exp(-x * x / 2.0) / math.sqrt(2.0 * math.pi) def pdf(x, mu=0.0, sigma=1.0): return phi((x - mu) / sigma) / sigma // Stay tuned for more functions.... Functions are an easy way for any user to extend the Python system. 36 Gaussian cumulative distribution function Q. What percentage of the total is less than or equal to z? Q. (equivalent). What is the area under the curve to the left of z? A. Gaussian cumulative distribution function. Gaussian probability density function (pdf) 0.4 0.3 0.2 0.1 0 −4 −3 −2 −1 0 1 2 3 4 −4 −3 −2 −1 0 1 2 3 4 37 Typical application: SAT scores (lowest=400, highest=1600, μ=1019, σ=209) Q. In 20xx NCAA required at least 820 for Division I athletes. What fraction of test takers did not qualify?? A. About 17%, since Φ(820, 1019, 209) = 0.17050966869132111....0191 1.0.0143 0.75.0095 0.5.0047 0.25 0 0 601 1019 1437 601 1019 1437 820 820 38 Gaussian CDF implementation Q. No closed form for Gaussian CDF Φ. How to implement? A. Use Taylor series. def cdf(z, mu=0.0, sigma=1.0): z = float(z - mu) / sigma if z < -8.0: return 0.0 if z > 8.0: return 1.0 total = 0.0 term = z Taylor series goes to infinity i = 3 Stop when close enough while total != total + term: Numerical Integration total += term term *= z * z / float(i) i += 2 return 0.5 + pdf(z) * total 39 Summary: a library for Gaussian distribution functions gaussian.py Best practice import sys import stdio Test all code at least once in main(). import math Also have it do something useful. def pdf(x, mu=0.0, sigma=1.0): x = float(x - mu) / sigma return math.exp(-x*x/2.0) / math.sqrt(2.0*math.pi) / sigma Q. What fraction of SAT test takers did not def cdf(z, mu=0.0, sigma=1.0): qualify for NCAA participation in 20xx? z = float(z - mu) / sigma if z < -8.0: return 0.0 if z > +8.0: return 1.0 % python3 gaussian.py 820 1019 209 total = 0.0 0.17050966869132106 term = z i = 3 while total != total + term: total += term Fun fact term *= z * z / i i += 2 We use cdf() to evaluate randomness in return 0.5 + total * pdf(z) submitted programs. def main(): z = float(sys.argv) mu = float(sys.argv) Bottom line sigma = float(sys.argv) YOU can build a layer of abstraction stdio.writeln(cdf(z, mu, sigma)) to use in any future program. if __name__ == '__main__': main() 40 Exercise: Odd odd(). Write a method odd() that takes three Boolean arguments and returns true if an odd number of arguments are true. Exercise: Odd odd(). Write a static method odd() that takes three Boolean arguments and returns true if an odd number of arguments are true. Exercise: Sigmoid sigmoid(). Write a static method sigmoid() that takes in a float argument x and returns the float value obtained from the formula 1/(1+e-x) Exercise: Sigmoid sigmoid(). Write a static method sigmoid() that takes in a float argument x and returns the float value obtained from the formula 1/(1+e-x) Exercise: Max3 max3(). Write a method max3() that takes in three int arguments and returns the value of the largest one. Add and overloaded function that does the same thing with three float values. Exercise: Max3 max3(). Write a static method max3() that takes in three int arguments and returns the value of the largest one. Add and overloaded function that does the same thing with three float values. Passing arguments and returning values Call by (object) reference. A function parameter variable can be used in the body of a function (same as local variable), except: parameter variable is initialised with the argument provided by the calling code. ==> call by object reference. Calling code initialises obj with a prints [0, 0, 100, 0, 0] Array are mutable objects. 47 Passing arguments and returning values Side effects with arrays. Don’t need to return a reference to the array. A function can produce a side effect of changing the value of arrays passed as arguments. Passing arguments and returning values Arrays as return values. But there are many situations where it is useful for a function to provide an array as a return value. Purpose: returning multiple objects of the same type to a client. Passing arguments and returning values Passing immutable arguments. (int, float, str, and bool) A function cannot produce the side effect of changing the value of immutable objects. 50 INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO Image sources http://www.intechopen.com/books/rheology-new-concepts-applications-and-methods/ a-practical-review-of-microrheological-techniques http://tweezpal.natan.si http://www.albartlett.org/articles/art2000jan.html http://laser.physics.sunysb.edu/~vwang/beam-propagation/ http://www.nature.com/neuro/journal/v14/n12/full/nn.2958.html http://www-cdf.fnal.gov/physics/new/top/2012/WHel9ifb/ http://en.wikipedia.org/wiki/Deutsche_Mark#mediaviewer/File:DEU-10m-anv.jpg INTRO TO PROGRAMMING IN PYTHON SEDGEWICK・WAYNE・DONDERO 5. Functions and Libraries Basic concepts Case study: Digital audio Application: Gaussian distribution Modular programming Libraries, and Modules Modular programming Organize programs as independent modules that do a job together. Why? Easier to share and reuse code to build bigger programs. Facts of life Support of modular programming has been a holy grail for decades. Ideas can conflict and get highly technical in the real world. main(): Def. A program is a set of statements with standard input/output. kept in python files, denoted module.py Def. A function is a set of statements with defined input/output. Def. A module is a set of related functions for use by other programs. Def. A library is a set of related modules for use by other programs (e.g. pygames). can be both a module Def. A client is a program or function that uses functions in other modules. and client 53 Fundamental abstractions for modular programming Client API Implementation Client Implementation Applications programming interface (API) Code that calls a Code (in a module) that Defines signatures, describes methods. module's function. implements a function. gaussian.py gaussianplot.py... gaussian module def pdf(x, mu=0.0, sigma=1.0): def main(): x = float(x - mu) / sigma... return math.exp(-x*x/2.0) / y[i] = gaussian.pdf(x[i]) double pdf(double x) Gaussian probability math.sqrt(2.0*math.pi) / sigma density function...... double cdf(double x) Gaussian cumulative distribution function 54 Libraries, and Modules 5 (simple) steps to create and use a module: 1.Import the module. 2.Qualify function calls in the client. 3.Compose a test client for the module. 4.Eliminate global code in the module. 5.Make the module accessible to the client. 55 Library: Programmatic Flow For now, place module in 5 same directory as client. 1 client imports modules 2 Implementation Client (no main) Module (has main = test client) 3 NB!: remove arbitrary global code 4 56 Random Numbers “ The generation of random numbers is far too important to leave to chance. Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. ” Jon von Neumann (left), ENIAC (right) Example: StdRandom Module Developed for this course, but broadly somewhat useful Implement methods for generating random numbers of various types. API First step in developing a library: Articulate the API! 58 StdRandom details Implementation Typical client import stdrandom import sys import stddraw def main(): N = int(sys.argv) for i in range(N): x = stdrandom.gaussian(0.5, 0.2) y = stdrandom.gaussian(0.5, 0.2) stddraw.point(x, y) stddraw.show(1) if __name__ == '__main__': main() stdrandom.py randompoints.py You could implement many of these methods, but now you don't have to! Stress testing: program does not crash when client does not follow contract % python randompoints.py 10000 59 Exercise 1.2.24 One way to generate a random number taken from the Gaussian distribution is to use the Box-Muller formula where u and v are real numbers between 0 and 1 generated by the random.uniform() method. Write a method gaussian that generates a standard random Gaussian variable Exercise 1.2.24 One way to generate a random number taken from the Gaussian distribution is to use the Box-Muller formula where u and v are real numbers between 0 and 1 generated by the random.uniform() method. Write a method gaussian that generates a standard random Gaussian variable def double gaussian() : # use the Box-Muller formula u = random.uniform() v = random.uniform() return math.sin(2*math.pi*v)*math.sqrt(-2*math.log(u)) Best practices Small modules Separate and classify small tasks. Implement a layer of abstraction.... Independent development def main(): N = Integer.parseInt(args); Code client before coding implementation. for i in range(N): stdio.writef(" %2d " , uniform(100)) stdio.writef("%8.5f ", uniform(10.0, 99.0)) Anticipate needs of future clients. stdio.writef("%5b " , bernoulli(.5)) stdio.writef("%7.5f ", gaussian(9.0,.2)) stdio.writeln();... % python3 stdrandom 5 61 21.76541 true 9.30910 57 43.64327 false 9.42369 Test clients 31 30.86201 true 9.06366 92 39.59314 true 9.00896 Include main() test client in each module. 36 28.27256 false 8.66800 Do more extensive testing in a separate module. 62 Unit Testing Unit test. Include main() to test each library. 63 Using a Module use module name to invoke method Stress testing: program does not crash when client does not follow contract 64 Exercise 2.2.1 Exercise 2.2.1 import math import stdio import sys def cosh(x): return (math.exp(x) + math.exp(-x)) / 2.0 def sinh(x): return (math.exp(x) - math.exp(-x)) / 2.0 def tanh(x): return sinh(x) / cosh(x) def main(): x = float(sys.argv) stdio.writef("sinh(%f) = %f\n", x, sinh(x)) stdio.writef("cosh(%f) = %f\n", x, cosh(x)) stdio.writef("tanh(%f) = %f\n", x, tanh(x)) if __name__ == "__main__": main() Example: StdArray Module Input Convention Sierpinski Barnsley Fern Modular Programming: StdRandom, StdArray and IFS (client) Discrete Distribution Discrete distribution. Given an array of weights (that sum to 1), choose an index at random with probability equal to its weight. 72 Example: stdstats module Developed for this course, but broadly useful Implement methods for computing statistics on arrays of real numbers. Available for download at booksite (and included in introcs software). stdstats module float max(float[] a) largest value float min(float[] a) smallest value float mean(float[] a) average float var(float[] a) sample variance API float stddev(float[] a) sample standard deviation float median(float[] a) plot points at (i, a[i]) void plotPoints(float[] a) plot points at (i, a[i]) void plotLines(float[] a) plot lines connecting points at (i, a[i]) void plotBars(float[] a) plot bars to points at (i, a[i]) Easy to implement, but easier to use! 73 Exercise: Mean and Std Calculations Calculate the mean and standard deviation of the following set {1,4,5,7,8,11}? Exercise: Mean and Std Calculations Calculate the mean and standard deviation of the following set {1,4,5,7,8,11}? StdStats Details Exercise V Plotting Modular programming: StdStats, StdRandom, and Gaussian client Experiment Prediction (more detailed) Flip N coins. Run experiment trials times. How many heads? How many heads? Prediction: Expect N/2. def binomial(n, p=0.5): heads = 0 for i in range(n): if bernoulli(p): heads += 1 return heads stdrandom.py Goal. Write a program to validate predictions. 79 Example of modular programming: Bernoulli trials import... bernoulli.py def main(): Bernoulli simulation n = int(sys.argv) trials = int(sys.argv) Get command-line arguments (trials experiments of N flips). freq = stdarray.create1D(n+1, 0) Run experiments. Keep track of for t in range(trials): heads = stdrandom.binomial(n, 0.5) frequency of occurrence of each freq[heads] += 1 return value. norm = stdarray.create1D(n+1, 0.0) for i in range(n+1): Normalize to between 0 and 1. Plot norm[i] = 1.0 * freq[i] / trials histogram. phi = stdarray.create1D(n+1, 0.0) Plot theoretical curve. stddev = math.sqrt(n)/2.0 for i in range(n+1): phi[i] = gaussian.pdf(i, n/2.0, stddev) % python bernoulli.py 20 10000 stddraw.setCanvasSize(1000, 400) stddraw.setYscale(0, 1.1 * max(max(norm), max(phi))) stdstats.plotBars(norm) stdstats.plotLines(phi) stddraw.show() if __name__ == '__main__': main() 80 Dependency Graph Enables development of complicated programs via simple independent modules. 81 Why modular programming? Modular programming enables Independent development of small programs. Every programmer to develop and share layers of abstraction. Self-documenting code. Fundamental characteristics Separation of client from implementation benefits all future clients. Contract between implementation and clients (API) benefits all past clients. Challenges How to break task into Client API Implementation independent modules? How to specify API? 82