class: center, middle, inverse, title-slide .title[ # ISA 419: Data-Driven Security ] .subtitle[ ## 03: Python Functions ] .author[ ###
Fadel M. Megahed, PhD
Professor
Farmer School of Business
Miami University
@FadelMegahed
fmegahed
fmegahed@miamioh.edu
Automated Scheduler for Office Hours
] .date[ ### Spring 2025 ] --- ## Quick Refresher of Last Class ✅ Use pseudocode to map out a problem. ✅ Python syntax, data types, and data structures. ✅ Convert data types using type casting. ✅ Manipulate lists and use methods on lists. --- ## Learning Objectives for Today's Class - Understand the anatomy of a Python function, use arguments correctly, and construct your first function. - Utilize built-in and anonymous functions (`map`, `lambda`, `filter`). - Analyze your second dataset. --- class: inverse, center, middle # The Anatomy of a Python Function --- ## One Motivation for Functions - **Reusability**: Functions allow you to reuse code. <img src="https://miro.medium.com/v2/resize:fit:720/format:webp/1*qIS9MRHvCR5g-CgRU_cAQw.png" alt="A schematic of the DRY principle, with the acronym is explained as Do not repeat yourself. Then, the figure states that this is the first rule of coding" width="62%" style="display: block; margin: auto;" /> .footnote[ <html> <hr> </html> **Source:** Sonika Baniya (2021). [First rule of coding: DRY (Don't Repeat Yourself)](https://sonikabaniya.medium.com/first-rule-of-coding-dry-dont-repeat-yourself-cfecc19449a5). ] --- ## What is a Function? - A function is a **block of reusable code** that only runs when called. <img src="data:image/png;base64,#../../figures/functions.png" alt="Three advantages of functions: modularity, abstraction, and organization." width="90%" style="display: block; margin: auto;" /> .footnote[ <html> <hr> </html> **Image Credits:** Created by the author (Fadel M. Megahed) for our ISA 419 course. ] ??? **Modularity:** Functions allow you to reuse code in different programs. **Abstraction:** Functions allow you to focus on the big picture. **Organization:** Functions allow you to break down your code into smaller, more manageable pieces. --- ## Recall: Python List Functions
−
+
04
:
00
.panelset[ .panel[.panel-name[Task] - In [class02](https://fmegahed.github.io/isa419/spring2024/class02/02_python_basics.html), we introduced the following functions: `len()`, `max()`, `min()`, `sum()`, `sort()`, `index()`, `append()`, `pop()`, and `remove()`. - For each of the above functions, what do you expect the function to **return**? - How is the name of the function related to the **action** it performs? ] .panel[.panel-name[Q1] 1. For each of the above functions, what do you expect the function to **return**? .font90[ .can-edit.key-activity5a[ - `len()`: Edit me. - `max()`: Edit me. - `min()`: Edit me. - `sum()`: Edit me. - `sort()`: Edit me. - `index()`: Edit me. - `append()`: Edit me. - `pop()`: Edit me. - `remove()`: Edit me. ] ] ] .panel[.panel-name[Q2] - How is the name of the function related to the **action** it performs? .can-edit.key-activity5b[ - Edit me. ] ] ] --- ## The Anatomy of a Python Function ``` python def add_numbers(a, b): # `A: The function definition` """ This function sums two numbers """ # `B: The docstring` result = a + b # `C: The body of the function` return result # `C: The body of the function` # Using the function add_numbers(3, 5) # `D: Calling the function` ``` ``` ## 8 ``` .footnote[ <html> <hr> </html> **Footnotes:** - Everything **within the function**, post the definition line, **is indented**. - Vertical spacing here is for clarity, but not required (and likely violates Python's best practies). ] --- ## The Anatomy of a Python Function (Cont.) .font80[ **A: The function definition:** - `def` is a .bold[keyword] that tells Python you are defining a function. - `add_numbers` is the .bold[name] of the function, which should always be followed by parentheses and a colon. - `a` and `b` are the .bold[parameters] of the function. **B: The docstring:** - Optional: A .bold[docstring] is a string that describes what the function does. **C: The body of the function:** - This is where the function does its work. - The body is indented. - Typically includes a `return` statement at the end. **D: Calling the function:** - This is where you .bold[call] the function, i.e., tell Python to execute the code inside your function. ] --- ## Python Parameters vs Arguments .pull-left[ - **Parameters** are the variables in the function definition. + `a` and `b` are the parameters in the `add_numbers` function. - **Arguments** are the values passed to the function when it is called. + `3` and `5` are the arguments in the `add_numbers` function. ] .pull-right[ ``` python def add_numbers(a, b): # `A: The function definition` """ This function sums two numbers """ # `B: The docstring` result = a + b # `C: The body of the function` return result # `C: The body of the function` # Using the function add_numbers(3, 5) # `D: Calling the function` ``` ``` ## 8 ``` ] --- ## Python Parameters and Arguments Python allows for several methods of passing arguments to a function. These include, but are not limited to the following: - **Positional Arguments**: The arguments are passed to the function in the order in which they are defined. - **Keyword Arguments**: The arguments are passed to the function with the parameter name. - **Combination of Positional and Keyword Arguments**: The arguments are passed to the function in the order in which they are defined, .bold[followed by the keyword arguments]. --- ## Class Activity: Modify the `add_numbers` Function
−
+
03
:
00
Modify the function `add_numbers` to take a list of numbers and return the sum of the numbers. ``` python # Hints: # ------ # 1. Change the function name to `sum_numbers` # (so you do not have two functions with the same name). # 2. Change the parameters to a single parameter named `numbers_list`. # 3. Capitalize on the fact that the parameter input is now a list. ``` --- ## Functions: Good Practices - **Function Name:** Choose a descriptive name for your function. + The name should describe what the function does. - **Type Hints:** You can specify the type of the parameters and the return type. + This is **not enforced by Python**, but it is a good practice. + For example: * `def add_numbers(a: int, b: int) -> int:` or * `def add_numbers(a: float, b: float) -> float:`. - **Docstrings:** Always include a docstring to describe what the function does. + This is a good practice and is used by Python's built-in `help()` function. - **Return Statement:** Always include a `return` statement. + If you do not include a `return` statement, the function will return `None`. --- class: inverse, center, middle # Built-In and Anonymous Functions in Python (`map`, `lambda`, `filter`) --- ## The `map` Function .pull-left[ - The `map` function applies a given function to each item of an *iterable* (e.g., `list`). Its synatx is: + `map(function, iterable)`. * The `function` is the function we want to apply. * The `iterable` is what we want to apply the function across. - The `map` function returns a **map object**, which is an iterator. - To get the **results**, you must *type convert* the map object to a list. ] .pull-right[ ``` python def square(x: float) -> float: """This function squares a number""" return x ** 2 # Using the map function numbers = [1, 2, 3, 4, 5] map_operation = map(square, numbers) squared_numbers = list(map_operation) print('The map operation:', map_operation, '\n\n', 'The squared numbers:', squared_numbers, sep ='\n') ``` ``` ## The map operation: ## <map object at 0x00000236C3582A40> ## ## ## ## The squared numbers: ## [1, 4, 9, 16, 25] ``` ] --- ## The `lambda` Function - The `lambda` function is an **anonymous function**, defined using the `lambda` keyword: + **Anonymous:** They are **not** declared in the standard manner by using the `def` keyword. + **Compact:** They allow writing functions in a concise way, often for short-term/throwaway functions. + **Single Expression:** The body of a lambda is limited to just one expression. No statements or annotations are allowed; the function body is purely a single expression. <img src="https://miro.medium.com/v2/resize:fit:4800/format:webp/0*4eRr7IZ3sP2ZAE8H.png" alt="A schematic of the lambda function, with the keyword lambda followed by the parameters and a colon, and then the expression to be evaluated." width="50%" style="display: block; margin: auto;" /> .footnote[ <html> <hr> </html> **Image Source:** John Vastola (2021). [Mastering Lambda Expressions in Python: A Hands-On Guide](https://levelup.gitconnected.com/mastering-lambda-expressions-in-python-a-hands-on-guide-e6f380701e96). ] --- ## The `lambda` Function (Cont.) ``` python numbers = [1, 2, 3, 4, 5] map_operation = map(lambda x: x ** 2, numbers) squared_numbers = list(map_operation) print( 'The map operation:', map_operation, '\n', 'The squared numbers:', squared_numbers, sep ='\n' ) ``` ``` ## The map operation: ## <map object at 0x00000236C3532740> ## ## ## The squared numbers: ## [1, 4, 9, 16, 25] ``` --- ## The `filter` Function .pull-left[ - The `filter` function constructs an iterator from elements of an iterable for which a function returns `True`. + Its syntax is: `filter(function, iterable)`. - The `filter` function returns a **filter object**, which is an iterator. - To get the **results**, you must *type convert* the filter object to a list. ] .pull-right[ ``` python def is_even(x: int) -> bool: """This function checks if a number is even""" return x % 2 == 0 # Using the filter function numbers = [1, 2, 3, 4, 5] filter_step = filter(is_even, numbers) even_numbers = list(filter_step) print('The filter operation:', filter_step, '\n', 'The even numbers:', even_numbers, sep ='\n') ``` ``` ## The filter operation: ## <filter object at 0x00000236C35B74F0> ## ## ## The even numbers: ## [2, 4] ``` ] --- ## Evaluating your Understanding so Far: A Kahoot .bold[Let's evaluate your understanding of the material so far] - Go to [Kahoot](https://kahoot.it) and enter the game pin shown on screen. - You will be asked to answer **7 multiple choice questions**. - You will receive **points** for answering each question **correctly** and **quickly**, i.e., your points are impacted by your speed in addition to obviously answering each question correctly. - The winner <svg viewBox="0 0 576 512" style="height:1em;position:relative;display:inline-block;top:.1em;fill:gold;" xmlns="http://www.w3.org/2000/svg"> <path d="M552 64H448V24c0-13.3-10.7-24-24-24H152c-13.3 0-24 10.7-24 24v40H24C10.7 64 0 74.7 0 88v56c0 35.7 22.5 72.4 61.9 100.7 31.5 22.7 69.8 37.1 110 41.7C203.3 338.5 240 360 240 360v72h-48c-35.3 0-64 20.7-64 56v12c0 6.6 5.4 12 12 12h296c6.6 0 12-5.4 12-12v-12c0-35.3-28.7-56-64-56h-48v-72s36.7-21.5 68.1-73.6c40.3-4.6 78.6-19 110-41.7 39.3-28.3 61.9-65 61.9-100.7V88c0-13.3-10.7-24-24-24zM99.3 192.8C74.9 175.2 64 155.6 64 144v-16h64.2c1 32.6 5.8 61.2 12.8 86.2-15.1-5.2-29.2-12.4-41.7-21.4zM512 144c0 16.1-17.7 36.1-35.3 48.8-12.5 9-26.7 16.2-41.8 21.4 7-25 11.8-53.6 12.8-86.2H512v16z"></path></svg> (i.e., the one with the most points after the 7 questions) receives a $10 Starbucks <svg viewBox="0 0 640 512" style="height:1em;position:relative;display:inline-block;top:.1em;fill:green;" xmlns="http://www.w3.org/2000/svg"> <path d="M192 384h192c53 0 96-43 96-96h32c70.6 0 128-57.4 128-128S582.6 32 512 32H120c-13.3 0-24 10.7-24 24v232c0 53 43 96 96 96zM512 96c35.3 0 64 28.7 64 64s-28.7 64-64 64h-32V96h32zm47.7 384H48.3c-47.6 0-61-64-36-64h583.3c25 0 11.8 64-35.9 64z"></path></svg> gift card. --- class: inverse, center, middle # Analyzing Your Second Dataset --- ## Analyzing a Simulated Equifax Breach Dataset
−
+
15
:
00
.panelset[ .panel[.panel-name[Task] - Download the `simulated_equifax_breach_data.csv` file from [Canvas](https://miamioh.instructure.com/courses/229048/files/34627330?module_item_id=5789098). - Load the dataset into [Google Colab](https://colab.research.google.com/). - Answer the questions in the next tabs. - You can work in groups of 2-3 students. ] .panel[.panel-name[Task 1] - Build on this code to print the first 5 rows of `ssn`. ``` python import pandas as pd # you will NOT need to have the same folder structure as I do equifax_df = pd.read_csv('../../data/simulated_equifax_breach_data.csv') # converting the pandas df into lists since we have not discussed pandas yet name = list(equifax_df['Name']) address = list(equifax_df['Address']) phone_num = list(equifax_df['Phone Number']) date_of_birth = list(equifax_df['Date of Birth']) ssn = list(equifax_df['Social Security Number']) driver_license = list(equifax_df['Driver License Number']) type(phone_num) # what type of object is this? ``` ``` ## <class 'list'> ``` ] .panel[.panel-name[Task 2] - Count the number of observations in our dataset, through the length of any of the lists. ``` python # Hints: # ------ # We have talked about this in class, in our discussion of list functions. ``` ] .panel[.panel-name[Task 3] - How many unique names are in the dataset? ``` python # Hints: # ------ # 1. Use `type casting` to convert the list into a `type that only stores unique values`. # 2. Use the `len()` function to count the number of unique names. ``` ] .panel[.panel-name[Task 4] - Use `map()` and `lambda` to extract area codes from phone numbers. ``` python # Hints: # ------ # 1. Use the `map()` function to apply a lambda function to each phone number. # 2. Use the `lambda` function to extract the first 3 digits of each phone number. # 3. Convert the map object to a `list` to see the results. ``` ] .panel[.panel-name[Task 5] - Use `filter()` to count the number of people from Butler County (i.e., area code 513). ``` python # No hints provided; you are a pro now :) ``` ] ] --- class: inverse, center, middle # Recap --- ## Summary of Main Points By now, you should be able to do the following: - Understand the anatomy of a Python function, use arguments correctly, and construct your first function. - Utilize built-in and anonymous functions (`map`, `lambda`, `filter`). - Analyze your second dataset. --- ## 📝 Review and Clarification 📝 1. **Class Notes**: Take some time to revisit your class notes for key insights and concepts. 2. **Zoom Recording**: The recording of today's class will be made available on Canvas approximately 3-4 hours after the end of class. 3. **Questions**: Please don't hesitate to ask for clarification on any topics discussed in class. It's crucial not to let questions accumulate.