1 / 51

Functions

Functions. CSE 1310 – Introduction to Computers and programming Alexandra Stefan University of Texas at Arlington. Overview. Review terminology: function call, arguments The need for functions: Write code once, reuse many times Less prone to error Function definition Syntax Parameters

murray
Download Presentation

Functions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Functions CSE 1310 – Introduction to Computers and programming Alexandra Stefan University of Texas at Arlington

  2. Overview • Review terminology: function call, arguments • The need for functions: • Write code once, reuse many times • Less prone to error • Function definition • Syntax • Parameters • Return value - optional • Using functions • Function definition vs function call • Parameters vs arguments • Flow of control: from caller program, to function implementation, and then back to the caller program • Namespaces (separate variables local to the function from the rest) • The main code • Import functions written in other files • Function vs procedure

  3. Review:Function and method call • Functions • E.g.: N= len("today") • function_name(argument1, argument2,..) • It may take none, one, or more arguments • It may or may not return a value(an object) • If it returns a value, this value can be saved/mapped to a variable with an assignment statement • In many programming languages, a function that does not return a value, is called a procedure. • E.g.: print("today") • Methods • E.g.: my_str = "today".upper() • object.method_name(argument1, argument2, …) • Dot notation • List of available methods: hit ‘Tab’ after the dot • Invoked/called function • The parenthesis, (), make it a function or a method call. • See error: my_str() #'str' object is not callable • Difference between a variable (object name) and a function call

  4. New material:Write our own functions • Why do we need functions? • To make our life easier! • Easier to read and write programs • Easier to test and debug • Easier to share • We’ll see that soon.

  5. An Example: Numerical User Input • In lots of programs, we use a line like: N = int(input("please enter a number: ")) • If the user does not enter a number, the program crashes. • What is wrong with that? • Imagine registering for classes. You have to enter a course number. If you enter by accident 131a instead of 1310, do you want: • To get a useful error message, or • Your browser to crash.

  6. An Example: Numerical User Input • Good programming style: never write code that can crash. That means that… • You should do input validation for every user input in every homework task. • Sample problem: Given 3 integers, verify that they can be the lengths of sides of a triangle. Perform input validation for all of them (that is keep asking for an input, until an integer is entered).

  7. Code for input validation: # It keeps asking for user input, until a valid one is entered. x_str= input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str= input("Enter an integer ") x_int= int(x_str) • Code for triangle verification (without input validation): # Input 3 values: a,b,c. Verify that they form a triangle. a = int(input("a=")) b = int(input("b=")) c = int(input("c=")) if (a+b>=c) and (a+c>=b) and (b+c>=a): print("It is a triangle") else: print("It is not a triangle")

  8. Notice that I did not change the name for x_str into a_str, b_str, c_str. The reason for that is: - Fewer changes are less prone to error - These lines perform the same operation. I only modified what I had to. But what if I wanted to display a specialized message like “a =”,“b =”,“c =”? I would need to make at least 6 changes. What if I wanted to change the input validation altogether? • Combine the two programs: # Input 3 values: a,b,c. Verify that they form a triangle. x_str= input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str= input("Enter an integer ") a = int(x_str) x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer ") b = int(x_str) x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer ") c = int(x_str) if (a+b>= c) and (a+c>=b) and (b+c>=a): print("It is a triangle") else: print("It is not a triangle") What proportion of this code solves the required problem and what proportion is code duplication? Almost half an half! It is also a bit hard to read!

  9. I would like to have a way to write the input validation code once, and then easily refer to it (without making multiple copies of it). In order to be able to refer to it, I have to give it a name. Then I can refer to it with that name. That will be the function name. • Combine the two programs: # Input 3 values: a,b,c. Verify that they form a triangle. x_str= input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str= input("Enter an integer ") a = int(x_str) x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer ") b = int(x_str) x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer ") c = int(x_str) if (a+b>= c) and (a+c>=b) and (b+c>=a): print("It is a triangle") else: print("It is not a triangle")

  10. I would like to have a way to write the input validation code once, and then easily refer to it (without making multiple copies of it). In order to be able to refer to it, I have to give it a name. Then I can refer to it with that name. That will be the function name. • What if it could look somewhat like this? # Input 3 values: a,b,c. Verify that they form a triangle. a = get_valid_int() b = get_valid_int() c = get_valid_int() if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle")

  11. I would like to have a way to write the input validation code once, and then easily refer to it (without making multiple copies of it). In order to be able to refer to it, I have to give it a name. Then I can refer to it with that name. That will be the function name. • What if it could look somewhat like this? # Input 3 values: a,b,c. Verify that they form a triangle. a = get_valid_int() b = get_valid_int() c = get_valid_int() if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle") • Advantages: • Easier to read • Shorter • Less code duplication • If I need to make a change, it will be in one place, namely in the code that implements the get_valid_int function.

  12. Associate the code with the name get_valid_int #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(): x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer: ") x = int(x_str) return x # main program a= get_valid_int() b = get_valid_int() c = get_valid_int() if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle") • Function definition: • Associates the code with a name • Specifies whether or not some value computed by this code is needed later on using the return statement. Here value x will be needed. • Has a specific syntax

  13. Make get_valid_int more flexible #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(): x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer: ") x = int(x_str) return x # main program a= get_valid_int() b = get_valid_int() c = get_valid_int() if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle") What if I wanted to show “a=“, “b=“, “c= “instead of “Enter an integer”?

  14. Make get_valid_int more flexible #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(): x_str = input("Enter an integer: ") while (not x_str.isdecimal()): print("The input was not an integer") x_str = input("Enter an integer: ") x = int(x_str) return x # main program a= get_valid_int() b = get_valid_int() c = get_valid_int() if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle") What if I wanted to show “a=“, “b=“, “c= “instead of “Enter an integer”? I will need to send some information to my function: done with function arguments I can change my function to take an argument, and I pass in the text that I want as the argument.

  15. Terminology #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(input_message): x_str = input(input_message) while (not x_str.isdecimal()): print("The input was not an integer") x_str = input(input_message) x = int(x_str) return x # main program a= get_valid_int("a= ") b = get_valid_int("b= ") c = get_valid_int("c= ") if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle") What if I wanted to show “a=“, “b=“, “c= “instead of “Enter an integer”? I will need to send some information to my function: done with function arguments I can change my function to take an argument, and I pass in the text that I want as the argument. Terminology: - argument (in function call) - parameter (in function definition)

  16. Function definition “The Practice of Computing Using Python” Punch & Enbody

  17. Function definition - deffct_name(parameter): - parameter(s) - code - return value Function call - arguments - after executing, the function call expression will be replaced by the computed return value of the function. - practice: see how the flow of control goes (use the debugger as well) What is the first line of code that executes when we run this program? • Let’s examine the Python syntax of the code we wrote: #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(input_message): x_str = input(input_message) while (not x_str.isdecimal()): print("The input was not an integer") x_str = input(input_message) x = int(x_str) return x # main program a= get_valid_int("a= ") b = get_valid_int("b= ") c = get_valid_int("c= ") if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle")

  18. Function definition - deffct_name(parameter): - parameter(s) - code - return value Function call - arguments - after executing, the function call expression will be replaced by the computed return value of the function. - practice: see how the flow of control goes (use the debugger as well) What is the first line of code that executes when we run this program? It is: a = get_valid_int("a= ") • Let’s examine the Python syntax of the code we wrote: #Input 3 values: a,b,c. verify if they could form a triangle. defget_valid_int(input_message): x_str = input(input_message) while (not x_str.isdecimal()): print("The input was not an integer") x_str = input(input_message) x = int(x_str) return x # main program a= get_valid_int("a= ") b = get_valid_int("b= ") c = get_valid_int("c= ") if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle")

  19. The "Main" Code • In order for a Python file to do something, it must include some code outside function definitions. • This code that is outside definitions is the place where Python starts executing the code form a file. It is called the main code of the program. • Until we did functions, the entire code was outside function definitions. • From now on, we will place all of the code in functions, except for the main code which will be just a function call to get Python to start executing.

  20. Code organization • For each problem, we will identify subproblems and write a function for each one of the subproblems. • We will also write a function for the main functionality of the program. We will call it main(). It will contain mostly function calls. It will give a high-level view of the program functionality. • The main code (the place where Python will start executing) will be a function call to the main() function

  21. Flow of control with functions • Flow of control that we have seen: • Sequential • statements executed in the order that they appear • If-else, while, for • With functions: • The flow of control jumps from invocation call (in the calling program, or caller) to the function definition (the callee) and then back to the invocation call statement (in the calling program). • Namespace: - later • Each function execution has it’s own namespace • Local variables exist only in the function namespace • Variables from the caller’s namespace, do not exist in the callee namespace • Local (callee) variable names shadow caller variable names: • if the same variable name appears both in the caller and the callee, if you change the local variable (in the callee), the one in the caller will not change.

  22. Flow of control a = get_valid_int("a= ") get_valid_int("a= ") - have input_message map to string "a=" - execute the code in the get_valid_int function - the result of executing get_valid_int is the integer value of x (say 5), called return value Replace get_valid_int("a= ") with that integer value: a = 5 a = 5 a will map to that value (5) b = get_valid_int("b= ") • Flow of control: # Input 3 values: a,b,c. Verify that they form a triangle. defget_valid_int(input_message): x_str = input(input_message) while (not x_str.isdecimal()): print("The input was not an integer") x_str = input(input_message) x = int(x_str) return x # main program a= get_valid_int("a= ") b = get_valid_int("b= ") c = get_valid_int("c= ") if (a+b>= c) and (a+c>= b) and (b+c>= a): print("It is a triangle") else: print("It is not a triangle")

  23. Function call and expression evaluation • Similarity between: • a = get_valid_int("a= ") • a = 1+4 • They both • First evaluate the expression on the right-handside • Then replace the expression (get_valid_int("a= ") and 1+4) with the value • Execute instruction: a = value, which maps a to value.

  24. Function • A small program that performs a specific task: A function must do one thing • If it does more than one thing, it should be redesigned. • Encapsulation: (implementation) details are hidden from us

  25. Why functions? • Better code: easier to read • Divide-and-conquer: • Divide a larger problem in smaller problems that can be solved individually with functions • make programs easier to write • Decoupling • Prevents you from modifying code that is irrelevant for this task • Abstraction • A function provides an interface to an implementation of a solution • Hides away the implementation details • Code reuse • You write and test it once, reuse it however many times you need • Code sharing • Others can use or even improve your function • Others can use your function, while you are still working on it!!! • Security • Easier to test and verify a function • Verified functions can then be combined together and verified again • Simplification and readability • Avoids duplication of code.

  26. Flow of control and namespace • The flow of control jumps from invocation call (in the calling program, or caller) to the function definition (the callee) and then back to the invocation call statement (in the calling program). • Namespace: • Each function execution has it’s own namespace • Local variables • Function parameters and • Variables defined in the function code • They exist only in the function namespace • Variables from the caller’s namespace, do not exist in the callee (function) namespace • Local (callee) variable names shadow caller variable names: • if the same variable name appears both in the caller and the callee, if you change the local variable (in the callee), the one in the caller will not change. – There are exceptions to this when the caller is main code (not part of a function)

  27. Function execution and namespaces • Function definition: • Example function call: • Processing: def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq)

  28. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Assume the user entered number 15. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Main Namespace: n = 15

  29. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Function call. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Main Namespace: n = 15

  30. Function execution and namespaces • Function definition: • Example function call: • Initializing function call: • Create new namespace. • Assign values to parameters. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 Main Namespace: n = 15

  31. Function execution and namespaces • Function definition: • Example function call: • Assigning values to args: • It is an assignment operation: • x = value of n from caller namespace def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 Main Namespace: n = 15

  32. Function execution and namespaces • Function definition: • Example function call: • Processing this line: def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 Main Namespace: n = 15

  33. Function execution and namespaces • Function definition: • Example function call: • Processing this line: def square(x): result = 225 return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 result = 225 Main Namespace: n = 15

  34. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Function returns a value. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 result = 225 Main Namespace: n = 15

  35. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Function returns a value. • Must transfer that value to caller. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Square Namespace: x = 15 result = 225 Main Namespace: n = 15 sq = 225

  36. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Normal print statement, printssomething. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Main Namespace: n = 15 sq = 225

  37. Function execution and namespaces • Function definition: • Example function call: • Processing this line: • Note: the namespace for square has disappeared. def square(x): result = x*x return result n = int(input("enter a number:")) sq = square(n) print("the square of", n, "is", sq) Main Namespace: n = 15 sq = 225

  38. Understanding Function Evaluation • Every function evaluation involves: • a calling line of code • the namespace of the calling line • arguments provided by the calling line of code • the function that we actually call • the namespace of the function call • the parameters: the names of the arguments that the function uses • the body of the function • (optionally) a return value of the function

  39. Calling a Function • When we call a function: • A new namespace is created. • The first variables in the new namespace are the parameters of the function. • The parameters are assigned values obtained from the calling line, using the namespace of the calling line. • The next line of code that is executed is the first line of the body of the function.

  40. Executing a Function Call • When the body of the function starts executing, code execution follows the same rules we have been using, except that: • The only namespace visible is the namespace of the function call. • The namespace of the calling line (or any other namespaces) is invisible.

  41. Completing a Function Call That Returns a Value • When, while executing the body of a function, we find a return statement: • The expression after the return keyword is evaluated. • The value of that expression is transferred to the calling line and used by the calling line. • From that point on, the code resumes execution from the calling line. • The visible namespace becomes again the namespace of the calling line. • The namespace of the function call disappears. • Any values computed by the function call, that were not returned, are lost forever.

  42. Defining a procedure (a function with no return value) def print_greeting(name): print("hello,", name, ", how are you?“) >>> print_greeting("mary") hello, mary, how are you? • Function print_greeting does not compute and return a value, it just does something useful.

  43. Import a function from a file (Why?) • Functions written in one file can be used in another • Assume that our get_valid_int function is saved in file valid_input_file • Version 1 • First import the name of the file: import filename • Usage (with filename): instead of function_name, use filename.function_name • Version 2 • Import all the definitions in the file: from filename import * • Usage: function_name • Version 3 - best • Import only the desired function definition: from filename import function_name • Usage: function_name • Avoid name collision in cases where you have another function or variable with the same name as a function that you are importing. import valid_input_file a = valid_input_file.get_valid_int("Enter a: ") from valid_input_file import * a = get_valid_int("Enter a: ") from valid_input_file import get_valid_int a = get_valid_int("Enter a: ")

  44. Import files • When asked to import a file, Python looks in the local directory and at other locations specified by the Python path. In order to ask it to look at another directory of your choice, you have to add it to the path: import sys sys.path # see the current path sys.path.append('C:\\Users\\Alex_2\\Desktop\\_code\\my_libraries') sys.path # notice that your directory was added to the list • If you modify the sys.pathas shown above, it will be reset (to the original value) when you restart the Shell • You can develop your own library/collection of functions

  45. How to write a function(Chapter 6.3.6) • Does one thing. If it does too many things, it should be broken down into multiple functions (refactored) • Readable. How often should we say this? If you write it, it should be readable • Reusable. If it does one thing well, then when a similar situation (in another program) occurs, use it there as well. “The Practice of Computing Using Python” Punch & Enbody

  46. More on function design(Chapter 6.3.6) • Complete. A function should check for all the cases where it might be invoked. Check for potential errors. • Not too long. Kind of synonymous with do one thing. Use it as a measure of doing too much. “The Practice of Computing Using Python” Punch & Enbody

  47. What happens when you modify, inside a function, an object that was passed as an argument? It depends on the object and the type of modification. Sometimes that object will also be modified in the caller space, and other times it will not. IMPORTANT TOPIC: PARAMETER PASSING # The int in the caller space will NOT be affected by this change. defmodify_an_int(x): print("in modify_an_int, got: x =", x) x = 3 print("in modify_an_int, changed x to x =", x) # The list in the caller space will be affected by this change. defmodify_a_list(L): print("in modify_a_list, got L =", L) L.append('modify') print("in modify_a_list, changed L to L =", L) # the main function def main(): print("\nAnint can NOT be modified by a function:") x = 1 print("in main, x =",x) modify_an_int(x) print("back in main: after modify_an_int, x is not changed: x=",x) print("\nA list can be modified by a function:") L = [1,2,3] print("in main, L =",L) modify_a_list(L) print("back in main: after modify_a_list, L is changed: L=",L) main() # start executing the program

  48. Summary • Definition vs invocation/call: know how to do both • Parameters vs arguments • Definition • def,…, colon , parameters, indentation • Return statement • The docstring: a string describing what the function does • Using functions • Flow of control: jumps between main code and function definitions (when a function executes) • Namespaces: one for main, one for each function execution • Parameter passing • Functions are callable entities. Use ‘()’ after the name of the function • Import functions written in other files • Function vs procedure: procedure does not return a value • Will modifying an object (passed as argument) in the callee(function) namespace be reflected in the caller namespace? – It depends!

  49. “The Practice of Computing Using Python” Punch & Enbody

More Related