# Defining Functions --- CS 65 // 2021-02-23 ## Administrivia - In-person tutoring services now available + Walk-in hours 2-8pm, Monday through Thursdays + Peer Tutoring Lab in the basement of Cowles + Wear face masks and social distance - Tutors wont help with Exam 1 + However, they can help with the *concepts* - Reach out to me directly if you're stuck on Exam 1 ## Extra Credit Activities - [Songs for A New World](https://calendar.drake.edu/event/songs_for_a_new_world?utm_campaign=widget&utm_medium=widget&utm_source=Drake+University+Calendar) Livestream Performance + Thursday, 2/25 from 8:00 to 10:00am - [Global Citizen Forum](https://www.drake.edu/diversity/initiatives/globalcitizenforum2021/) + Conference on equity and inclusion in higher ed + March 3-5 # Exam 1 - Due on Thursday **before class** # Functions ## Functions are Subroutines - Recall that a **subroutine** is a "named algorithm" that we can reuse many times - In Python, subroutines are called **functions** - Notation borrowed from math + $f(x) = 2x + 1$ ## Defining Functions - In Python, you can define a function by doing: ```py def greet(first_name): print("Hello!") print("It is a pleasure to meet you,", first_name) ``` - When this function is defined, it can be "called" in the following way: ```py greet("Titus") ``` - `first_name` is the **parameter** of the function and `"Titus"` is the **argument** given to it above ## "Fruitful" Functions - Functions can also **return** values so that they can be used in other computations ```py twelve = round(3.14) * 4 ``` - To return a value, you must use a **return statement** ```py def square(num): return num*num ``` ## How Python Evaluates Expressions - When an expression includes a **function call**, the program pauses evaluating the expression and **steps into the function** and executes it - Once the function **returns a value**, it then resumes execution where it left off in the expression - If a function does not return a value, Python automatically returns the value `None` ## Example ```py def greet(first_name): print("Hello!") print("It is a pleasure to meet you,", first_name) def greet_both(name1, name2): greet(name1) greet(name2) def main(): your_name = input("What is your name? ") their_name = input("What is your partner's name? ") greet_both(your_name, their_name) main() ``` ## Another Example ```py from graphics import * import math def width(rect): x1 = rect.getP1().getX() x2 = rect.getP2().getX() return abs(x1-x2) def height(rect): y1 = rect.getP1().getY() y2 = rect.getP2().getY() return abs(y1-y2) def area(rect): return width(rect) * height(rect) def main(): win = GraphWin("Rectangle Facts") print("Click twice to draw a rectangle.") p1 = win.getMouse() p2 = win.getMouse() r = Rectangle(p1, p2) r.draw(win) print("The width of this rectangle is:", width(r)) print("The height of this rectangle is:", height(r)) print("The area of this rectangle is:", area(r)) main() ``` ## Variable Scope - When a variable is created inside a function, it is **locally scoped**, meaning that it is only accessible from inside that function. - This is a **feature** that allows functions to reuse variable names without worrying about variables declared somewhere else. - Variables declared outside of a function are **globally scoped** and all functions have read-access them. ## Drawing a Cloud - Let's write a function! - Suppose I want a function called `draw_cloud` that draws three white circles that look like a cloud ## Drawing a Cloud ```py from graphics import * def draw_cloud(x, y, win): center = Circle(Point(x, y), 50) center.setFill("white") center.setOutline("white") center.draw(win) right = Circle(Point(x + 50, y), 40) right.setFill("white") right.setOutline("white") right.draw(win) left = Circle(Point(x - 50, y), 40) left.setFill("white") left.setOutline("white") left.draw(win) def main(): win = GraphWin("Clouds", 500, 500) draw_cloud(300, 200, win) draw_cloud(100, 300, win) main() ``` # Lab Time