{ "cells": [ { "cell_type": "markdown", "id": "04fad87c", "metadata": { "id": "WdnFtGWOTkGo" }, "source": [ " \n", "\n", "\n", "# **Functions**" ] }, { "cell_type": "markdown", "id": "ae322244", "metadata": { "id": "DFi6mu9fvK43" }, "source": [ "## Defining a function\n", " A function is a block of code (related statements) that perform a specific task. This block of code only runs when you call the function. Therefore, functions are useful when you want to run part of your code repeatedly or when you want to put a complex part of your code into a separate sub-program to increase the readibility of your code.\n", "\n", "Below is a simple example of a function called `rectangle` in Python that computes the area and perimeter of a rectangle given its length `l` and its width `w`." ] }, { "cell_type": "code", "execution_count": 1, "id": "a739af35", "metadata": { "id": "zyg9SAMiy85f" }, "outputs": [], "source": [ "def rectangle(l,w):\n", " area=l*w\n", " perimeter=2*(l+w)\n", " return area, perimeter" ] }, { "cell_type": "markdown", "id": "d7527d56", "metadata": { "id": "Ph_OP4SwzoTS" }, "source": [ "As you can see, the function is defined using `def` keyword. The function name comes next; here it is called `rectangle`. The function takes the two input parameters `l` and `w` which should come after the function name inside parenthesis `()` followed by `:`. Note that the body of this function is defined by indentation. This function returns two outputs using the `return` statement.\n", "\n", "Note that a function can have none or multiple input and output arguments." ] }, { "cell_type": "code", "execution_count": 2, "id": "570afb2e", "metadata": { "id": "S_6ZuD6ZmFDP" }, "outputs": [], "source": [ "def add_numbers(num1, num2, num3):\n", " sum = num1 + num2 + num3\n", " print(\"sum: \", sum)" ] }, { "cell_type": "markdown", "id": "002b1c31", "metadata": { "id": "gtugUUyBrnJf" }, "source": [ "## Calling a function\n", "To call a function you can use the function name followed by parenthesis to pass along the arguments.\n", "\n", "The figure below shows how functions work. When you call a function (1), the program jumps to the code inside that function and executes it (2). After the function completes its execution, it returns a result/output. The program then resumes running from where it left off after the function call (3)." ] }, { "cell_type": "markdown", "id": "adab3b4a", "metadata": { "id": "p1SzP2jta6jA" }, "source": [ "![working-of-function-python.webp](../../images/working-of-function-python.webp)" ] }, { "cell_type": "markdown", "id": "d61fdecc", "metadata": { "id": "g8B3rnM3dsCD" }, "source": [ "There are multiple ways you can call a function based on your preferance or application. Below are some examples." ] }, { "cell_type": "code", "execution_count": 3, "id": "338b507a", "metadata": { "id": "d8FEktPZb1ha" }, "outputs": [], "source": [ "# First define the function\n", "def rectangle(l,w):\n", " area=l*w\n", " perimeter=2*(l+w)\n", " return area, perimeter" ] }, { "cell_type": "code", "execution_count": 4, "id": "9eb54e29", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "kbvnbuoE-Ewf", "outputId": "1e2844bb-4103-45a9-8cd8-e147a2c98cec" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rectangle 1: area = 8 , perimeter= 12\n", "rectangle 2: area = 8 , perimeter= 12\n", "rectangle 3: area = 800 , perimeter= 120\n" ] } ], "source": [ "# Call the function\n", "# syntax 1\n", "area1, per1= rectangle(4,2)\n", "print(\"rectangle 1: area =\",area1 ,\", perimeter=\",per1)\n", "\n", "# syntax 2\n", "area2, per2= rectangle(w=2,l=4)\n", "print(\"rectangle 2: area =\",area2 ,\", perimeter=\",per2)\n", "\n", "# syntax 3\n", "l3=40; w3=20\n", "rec3= rectangle(l3,w3)\n", "print(\"rectangle 3: area =\",rec3[0] ,\", perimeter=\",rec3[1])" ] }, { "cell_type": "markdown", "id": "42a670bf", "metadata": { "id": "IFStqj48--2v" }, "source": [ "❗Note the **different possible syntaxes** for input and output arguments above. Also note that in the second syntax, known as \"keyword arguments\", the order of the inputs is not important and you can switch. Here is another example:" ] }, { "cell_type": "code", "execution_count": 5, "id": "703b2374", "metadata": { "id": "sMS6MEcBo75W" }, "outputs": [], "source": [ "# define a function\n", "def divide(a,b):\n", " return a/b" ] }, { "cell_type": "code", "execution_count": 6, "id": "691469db", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "9cpmMaO7_GFF", "outputId": "84408ea0-2241-45c5-a83b-6dc8a4d22c2c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "syntax 1: 4.0\n", "syntax 2: 4.0\n" ] } ], "source": [ "# Now call the function\n", "\n", "# syntax 1: call function and print resut\n", "print(\"syntax 1:\", divide(8,2))\n", "\n", "# syntax 2: call function and print result\n", "print(\"syntax 2:\", divide(b=2, a=8))" ] }, { "cell_type": "markdown", "id": "3507d400", "metadata": { "id": "uWdTA0NRqiP-" }, "source": [ "## Extra: return to the BMI calculator! \n", "\n", "Do you remember the program you wrote to calculate BMI using if and else-statements in Python Notebook? Now we are going to reuse it by calling it multiple times without ending up unnecessarily long code.\n", "\n", "Our original code is below:" ] }, { "cell_type": "code", "execution_count": null, "id": "c54ca759", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Original code\n", "\n", "# Get input for age and weight\n", "weight = #Enter your weight in kilograms (float)\n", "height = #Enter your height in meters (float)\n", "\n", "\n", "# Calculate BMI\n", "bmi = weight / (height ** 2)\n", "\n", "# Determine BMI range\n", "if bmi < 18.5:\n", " category = \"underweight\"\n", "elif 18.5 <= bmi < 24.9:\n", " category = \"healthy weight\"\n", "elif 25 <= bmi < 29.9:\n", " category = \"overweight\"\n", "else:\n", " category = \"obese\"\n", "\n", "# Print results\n", "print(f\"Your BMI is {bmi:.2f}, which falls in the '{category}' range.\")" ] }, { "cell_type": "markdown", "id": "e7db6c3a", "metadata": { "id": "JN7Kj0u5wDn9" }, "source": [ "Now let's define the main code as a function, with a few adjustments:\n", "\n", "* The inputs are already defined in the brackets as parameters, so there is no need to ask the user for input.\n", "* You can `return` the parameters **bmi** and **category**, but using a `print` function to display them would also work and be more convenient in this case." ] }, { "cell_type": "code", "execution_count": 7, "id": "72f143d5", "metadata": { "id": "dM9HmDSPtnAh" }, "outputs": [], "source": [ "#Define the function\n", "\n", "def bmi_calculator(weight, height):\n", "\n", " # Calculate BMI\n", " bmi = weight / (height ** 2)\n", "\n", " # Determine BMI range\n", " if bmi < 18.5:\n", " category = \"underweight\"\n", " elif 18.5 <= bmi < 24.9:\n", " category = \"healthy weight\"\n", " elif 25 <= bmi < 29.9:\n", " category = \"overweight\"\n", " else:\n", " category = \"obese\"\n", "\n", " #return the parameters\n", " print(f\"Your BMI is {bmi:.2f}, which falls in the '{category}' range.\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "bc2d9d27", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "45bApeILuSIe", "outputId": "6da02cb3-7938-4204-858f-712354cd33fe" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your BMI is 22.34, which falls in the 'healthy weight' range.\n", "Your BMI is 40.40, which falls in the 'obese' range.\n", "Your BMI is 14.57, which falls in the 'underweight' range.\n", "Your BMI is 26.32, which falls in the 'overweight' range.\n" ] } ], "source": [ "# Now let's call the function\n", "\n", "#syntax 1\n", "bmi_calculator(70, 1.77)\n", "#syntax 2\n", "bmi_calculator(110, 1.65)\n", "#syntax 3\n", "bmi_calculator(weight=35, height=1.55)\n", "#syntax 4\n", "bmi_calculator(height= 1.90, weight= 95)" ] }, { "cell_type": "markdown", "id": "6a95df79", "metadata": { "id": "9f4bGRnoyHn5" }, "source": [ "✅ By defining the function `bmi_calculator`, you can apply the code multiple times without having to rewrite it, making your work easier and faster. Functions help in organizing the code better and make it more readable and maintainable." ] }, { "cell_type": "markdown", "id": "da7619d7", "metadata": { "id": "eh50UzKbGcab" }, "source": [ "## Parameter or argument?\n", "\n", "Note that these two terms may get confusing sometimes. In Python functions:\n", "\n", "* A __parameter__ is the variable used in the function definition.\n", "\n", "* An __argument__ is the value that is passed to the function when it is called." ] }, { "cell_type": "markdown", "id": "9a559f46", "metadata": { "id": "ffcrYUP4PVAy" }, "source": [ "## Required and default arguments\n", "\n", "A function should be given the correct number of arguments when it is called or it will give an error. For example, the rectangle function defined above requires exactly two arguments. However, you can set a default value for an input parameter when defining the function. In this case, if you call the function without the argument, **it uses the default value to compute the results**. Here is an example." ] }, { "cell_type": "code", "execution_count": 9, "id": "71759c04", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "eWdy_HYmPmbP", "outputId": "148fcb63-e42b-413b-c8e3-eba5ac3728a6" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8\n", "3\n" ] } ], "source": [ "# define a function\n", "def subtract(a,b=0):\n", " return a-b\n", "\n", "# call function and print resut\n", "print(subtract(8)) # a=8, b=0 (default)\n", "print(subtract(8,5)) # a=8, b=5 (input)" ] }, { "cell_type": "markdown", "id": "77094095", "metadata": { "id": "ECe7c7vuPs78" }, "source": [ "## Variable number of arguments\n", "\n", "You can have **variable number of parameters** in Python, but you have to indicate that in the function definition. That can be done by adding an asterisk `*` before the parameter name. Here is an example:" ] }, { "cell_type": "code", "execution_count": 10, "id": "bd660e85", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "i4tY3Xc1Pzn7", "outputId": "95c206ad-5eb7-4f43-88af-883308732e8e" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "720\n" ] } ], "source": [ "def multiplication(*numbers):\n", " result=1\n", " for num in numbers:\n", " result *= num\n", " return result\n", "\n", "print(multiplication(1,2,3,4,5,6))" ] }, { "cell_type": "markdown", "id": "058057a6", "metadata": { "id": "LVtHwK2IP5Fl" }, "source": [ "## Lambda functions (anonymous functions)\n", "\n", "Another way to quickly define a function in Python that has only one expression is using the `lambda` keyword instead of `def`. The correct syntax is: `lambda arguments : expression`. Here is an example which performs the same task as the `divide` and `substract` functions you saw earlier." ] }, { "cell_type": "code", "execution_count": 11, "id": "653fe8ed", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "qgCzsKX0P5xj", "outputId": "e6c5b96f-4126-44fe-e7e4-df6f9ed57d38" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.0\n" ] } ], "source": [ "divide2 = lambda x,y: x/y\n", "\n", "print (divide2(8,2))" ] }, { "cell_type": "code", "execution_count": 12, "id": "f7938471", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "48r2lLlYRd1i", "outputId": "6292fee9-b9cb-4ff8-e31b-2ab9a1d5a866" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "8\n" ] } ], "source": [ "substract2 = lambda a,b: a-b\n", "\n", "print(substract2(8,5))\n", "\n", "# with default value\n", "substract2 = lambda a,b=0: a-b\n", "\n", "print(substract2(8))" ] }, { "cell_type": "markdown", "id": "33cce53f", "metadata": { "id": "mOwSXyT-P_77" }, "source": [ "Lambda functions are mostly used when you require a nameless function for a short period of time, but a detailed explanation is outside the scope of this basic introduction." ] }, { "cell_type": "markdown", "id": "f2bab3c8", "metadata": { "id": "Z1VspaDwSOC6" }, "source": [ "------\n", "## Exercises: Functions\n", "\n", " When working with different cells (defining functions in one cell and calling them in another cell), ensure that you first run the cell where the functions are defined." ] }, { "cell_type": "markdown", "id": "b9e2ede5", "metadata": { "id": "gK1uQHEkamVt" }, "source": [ "____\n", "### **Exercise: Temperature conversion**\n", "Write a Python program that defines a function `temperature_converter()` to convert temperatures between Celsius and Fahrenheit. This function does not take any parameters, instead; it prompts the user to make a choice for the conversion direction and then to input the temperature. The function will then print the converted temperature.\n", "\n", "Conversion options:\n", "1. Celsius to Fahrenheit: °F = (°C * 9/5) + 32\n", "2. Fahrenheit to Celsius: °C = (°F - 32) * 5/9\n", "\n", "💡 Hint 1: Use the if-elif-else construction for the conversion logic and include the print statements **within** these cases.\n", "\n", "💡 Hint 2: First, write the main code and test if it works properly. Once it works correctly, define this main code as a function." ] }, { "cell_type": "code", "execution_count": null, "id": "c6727a4d", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Main code\n", "# Print the options\n", "print(\"Temperature Converter\")\n", "print(\"1. Celsius to Fahrenheit\")\n", "print(\"2. Fahrenheit to Celsius\")\n", "\n", "# Prompt the user to make a choice between 1 and 2\n", "choice = #Enter your choice (1 or 2) " ] }, { "cell_type": "code", "execution_count": null, "id": "b6f0f0c9", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# If option 1\n", "if choice == 1:\n", " # Prompt the user to enter temperature in Celsius\n", " # your code here\n", " # Celsius -> Fahrenheit\n", " fahrenheit = # your code here\n", " # Print the converted temperature\n", " print(f\"{celsius}°C is equal to {fahrenheit:.2f}°F\")\n", "\n", "# If option 2\n", "elif choice == 2:\n", " # Prompt the user to enter temperature in Fahrenheit\n", " fahrenheit = # your code here\n", " # Fahrenheit -> Celsius\n", " celsius = # your code here\n", " # Print the converted temperature\n", " print(f\"{fahrenheit}°F is equal to {celsius:.2f}°C\")\n", "\n", "else:\n", " # your code here" ] }, { "cell_type": "markdown", "id": "3082b3a0", "metadata": { "id": "mdquJ7YuxnPl" }, "source": [ "✅ If your code works properly, now define it as a function with a few adjustments. You don't need to use `return` since you can print the output directly within the function." ] }, { "cell_type": "code", "execution_count": null, "id": "9369d6a7", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "def temperature_converter():\n", "\n", " # your code here" ] }, { "cell_type": "markdown", "id": "378d7517", "metadata": { "id": "4YM6kvfayzrS" }, "source": [ "✅ Once you define the function, you can call and use it without needing a long piece of code each time. This makes your code more efficient, easier to read, and more convenient to maintain and reuse." ] }, { "cell_type": "code", "execution_count": null, "id": "f16e14db", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Call and test the function\n", "temperature_converter()" ] }, { "cell_type": "markdown", "id": "897fc2b2", "metadata": { "id": "HtVpFBzJLc8i" }, "source": [ "____\n", "### **Exercise: Battery life of a chip**\n", "\n", "Suppose that we have a chip, and we want to calculate how long it will take before its battery is fully exhausted. By calculating its dynamic and static power, we can easily obtain the time as:\n", "battery time = battery capacity /$( P_{dynamic} + P_{static})\n", "$\n", "\n", " But there are some parameters that we have to take into account to do that.\n", "\n", "* $V_{DD}$ : Supply voltage\n", "* $f$ : Clock frequency\n", "* $C$ : Capacitance\n", "* $α$ : Activity factor\n", "* $I$ : Leakage current\n", "\n", "The formulas needed to calculate the dynamic and static power are below:\n", "\n", "$P_{dynamic}$ = $ \\alpha C V_{DD}^2 f$\n", "\n", "$P_{static} = I V_{DD}$\n", "\n", "💡 Dynamic power: This is the power consumed by the chip during its active operation, such as processing tasks and running programs.\n", "\n", "💡 Static power: This is the power consumed by the chip when it is idle or in standby mode, due to leakage currents and other static effects. It will always draw power no matter what you do.\n", "\n", "Write Python code to calculate the time it takes for the battery to become fully exhausted. First, define functions for dynamic and static power consumption separately. Then, define a function for the chip's battery life." ] }, { "cell_type": "code", "execution_count": null, "id": "495dd1a4", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Define the dynamic power\n", "def dynamic_power(alpha, capacitance, supply_voltage, frequency):\n", " dynamic_power_value = # your code here\n", " return dynamic_power_value\n", "\n", "# call and test the function with a simple example\n", "print(dynamic_power(1, 2, 3, 4))" ] }, { "cell_type": "code", "execution_count": null, "id": "4a016eef", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Define the static power\n", "def static_power(leakage_current, supply_voltage):\n", " static_power_value = # your code here\n", " return static_power_value\n", "\n", "# call and test the function with a simple example\n", "print(static_power(2, 3))" ] }, { "cell_type": "code", "execution_count": null, "id": "a8c1d7d3", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# Define the chip battery\n", "def chip_battery(dynamic_power_value, static_power_value, battery_capacity):\n", " battery_time = # your code here\n", " return battery_time\n", "\n", "# call and test the function with a simple example\n", "print(chip_battery(10,2, 3))" ] }, { "cell_type": "markdown", "id": "11d62186", "metadata": { "id": "rrvwBcR10crK" }, "source": [ " After that, use the provided values for two different scenarios for the parameters and call the functions accordingly.\n", "\n", "**Scenario 1**\n", "* `battery_capacity = 30` (Ah)\n", "* `alpha = 0.1`\n", "* `capacitance = 10e-9` (F)\n", "* `supply_voltage = 2.0` (V)\n", "* `frequency = 100e6` (Hz)\n", "* `leakage_current = 100e-3` (A)\n", "\n", "**Scenario 2**\n", "* `battery_capacity = 52` (Ah)\n", "* `alpha = 0.1`\n", "* `capacitance = 20e-9` (F)\n", "* `supply_voltage = 4.0` (V)\n", "* `frequency = 10e6` (Hz)\n", "* `leakage_current = 50e-3` (A)" ] }, { "cell_type": "code", "execution_count": null, "id": "eec9e29b", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "print(\"Scenario 1:\")\n", "\n", "# Assign values\n", "alpha = 0.1\n", "capacitance = 10e-9 # F\n", "supply_voltage = 2.0 # V\n", "frequency = 100e6 # Hz\n", "leakage_current = 100e-3 # A\n", "battery_capacity = 30 # Ah\n", "\n", "# Call the functions\n", "dynamic_power_value = # your code here\n", "static_power_value = # your code here\n", "battery_time = # your code here\n", "\n", "# Print the results\n", "print(f\"Dynamic Power: {dynamic_power_value:.2f} W\")\n", "print(f\"Static Power: {static_power_value:.2f} W\")\n", "print(f\"Battery Time: {battery_time:.2f} hours\")" ] }, { "cell_type": "code", "execution_count": null, "id": "4f05e502", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "print(\"Scenario 2:\")\n", "\n", "# Assign values\n", "alpha = 0.1\n", "capacitance = 20e-9 # F\n", "supply_voltage = 4.0 # V\n", "frequency = 10e6 # Hz\n", "leakage_current = 50e-3 # A\n", "battery_capacity = 52 # Ah\n", "\n", "# Call the functions\n", "# your code here\n", "\n", "# Print the results\n", "# your code here" ] }, { "cell_type": "markdown", "id": "4ea51279", "metadata": { "id": "pq43n33cDYiH" }, "source": [ "____\n", "### **Exercise: Palindrome checker**\n", "\n", "Create a program that defines a function to check if a given string is a palindrome (reads the same forwards and backwards). Define a string variable and display whether it’s a palindrome or not. Test your code with some examples and make sure it's not case sensitive.\n", "\n", "First, remember how to make a word lowercase and how to reverse it. Once you have that in mind, you can start writing the program to solve the problem. You can use the example in the cell below." ] }, { "cell_type": "code", "execution_count": null, "id": "53036c78", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "# define a variable with a word stored in it\n", "word = \"Hello\"\n", "\n", "# Convert the word to lowercase\n", "lower = # your code here\n", "print(lower)\n", "\n", "# Reverse the word using slicing\n", "reverse = # your code here\n", "print(reverse)" ] }, { "cell_type": "code", "execution_count": null, "id": "b789673b", "metadata": { "tags": [ "skip-execution" ] }, "outputs": [], "source": [ "def palindrom_checker(word):\n", "\n", " word = # your code here\n", " revers_word=# your code here\n", "\n", " # your code here:\n", "\n", "\n", "palindrom_checker (\"Hello\")\n", "palindrom_checker (\"Bob\")" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst", "format_version": 0.13, "jupytext_version": "1.16.4" } }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.11" }, "source_map": [ 13, 20, 29, 38, 44, 52, 59, 63, 67, 77, 99, 103, 111, 127, 135, 161, 169, 193, 212, 216, 226, 232, 248, 254, 270, 276, 288, 305, 309, 316, 330, 343, 367, 371, 379, 383, 389, 418, 429, 440, 451, 472, 495, 514, 523, 537 ] }, "nbformat": 4, "nbformat_minor": 5 }