{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2022-06-28T19:00:00+00:00","date_modified":"2026-02-09T19:25:17.498497+00:00","extra_instructor_files":"","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":983,"instructions":"## Defining Your Own Functions\n\n![A picture of a box labelled \"Homemade Functions\"](functions_defining_homemade_box.png)\n\nYou can create your own functions in Python.\nIn fact, this is one of the most powerful features of programming \u2014 the ability to create your own functions.\n\n## Why Functions?\n\n- **Code reuse** so that we don't have to write the same statements repeatedly.\n- **Easier to debug** a chunk of code in isolation from the rest of the program.\n- **Clean decomposition** to break a program down into smaller pieces without keeping the whole thing in our mind at once.\n\nLets' talk about three major advantages of functions:\nFirst, they allow us to reuse code so that we don't have to write the same statements repeatedly.\nSecond, they allow us to debug a chunk of code in isolation from the rest of the program.\nThird, they let us break a program down into smaller pieces, and we don't have to worry about how the functions work internally.\n\n## Definition Syntax\n\n![Annotations mark each part of the function definition.  `def` is the define keyword.  `name` is the name of the function.  `(` and `)` are the parentheses.  `p1` and `p2` are parameters' names. `int` and `str` are the parameters' types. `,` is a comma, separating the parameters. `->` is dash and a greater than, forming an arrow. `bool` is the return type. `:` is a colon, ending the header. ](functions_defining_syntax.png)\n\nTo create a new function, first you write the `def` keyword (which stands for \"define\"), then the name of the function, an open parenthesis (`(`), each of the **parameters** separated by commas,\na closed parenthesis (`)`),\na dash and a greater than (`->`, representing an arrow),\nthe **return** type of the function, and a colon.\nFor _each_ parameter, you write: the name of the parameter, a colon, and the type of the parameter.\nThis entire line \u2014 including the parameters \u2014 is called the _function header_.\n\n## Function Body\n\n```python add-function\ndef add(left: int, right: int) -> int:\n    return left + right\n```\n\nWhen you call a function, you are executing the code stored in the _body_ of the function.\nEverything \"inside\" the body should be indented **4 spaces**.\nIn the block version, this is shown visually with a bar on the left.\nThe body must be there - in other words, it cannot be empty.\n\n\n## Naming a function\n\n* Try to use verbs.\n* Function names can only have letters, numbers, and underscores.\n* Function names cannot start with numbers.\n\nUsually, you should use a verb as the name of the function.\nThe name helps other programmers understand what the function does.\nNaming a function is just like naming a variable: You may only use letters, numbers, and underscores, and it cannot start with a number.\nTypically, the underscores are used to separate words in the names (since you cannot use spaces.)\n\n## Calling Your Functions\n\n```python add5-function\ndef add5(a_number: int) -> int:\n    return a_number + 5\n\nadd5(10)\nadd5(3)\n\n# To see the result, you will need to use print:\nprint(add5(10))\n```\n\nAfter you've defined a function, you can use it by calling the function.\nAs we did before, we combine the name of the function with calling parentheses.\nNote how we still pass in arguments.\nHere we call the function `add5` twice, first passing in the argument `10` and then calling it again with the argument `3`.\n\n## Control Flow\n\n![A function call being traced. The header is first, then an arrow labeled 1 jumps down to the next line after the body of the function. That line has a function call back to the start of the function labeled 2. Then the body executes one line at a time, until the return statement, which jumps the execution back to the function call.](functions_defining_control_flow.png)\n\nWhen a function is called, the _control flow_ jumps to the header of the function, where the arguments are assigned to the parameters.\nThen, the body of the function is executed one line at a time until a `return` statement is encountered or the function runs out of lines in its body.\nIn the diagram shown here, the first line executed is the header, but the second line executed is the last line of code where the function call is located.\nThen the third line is the first line of the body, and the fourth line is the line after that.\nThat line is the return statement, so execution returns to the line with the original function call.\n\n## Parameters\n\n```python subtract-function\ndef subtract(first: int, second: int) -> int:\n    return first - second\n\nprint(subtract(3, 8))\nprint(subtract(-2, 5))\n\nresult = subtract(10, 10)\nprint(result)\n```\n\nWhen you define a function, you can choose to add in **parameters** to the header.\nThese parameters will take on the value of the arguments when the function is called.\nThis can be very tricky to understand.\nEach argument exactly matches one parameter.\nIn the code below, the parameter `first` will match to 3, -2, and -10.\nThe parameter `second` will match to 8, 5, and 10.\nRemember, each function call happens one after the other.\n\n## Parameters and Types\n\n```python get_speed-function\ndef get_speed(distance: int, time: int) -> float:\n    return distance / time\n\nget_speed(6, 2)\nget_speed(3, 8)\n```\n\nIn modern Python, we specify the type of each parameter.\nSo far, we know of five types: int, str, float, bool, and None.\nAny time you call that function, the arguments must match the type of the parameter.\n\nTechnically, Python does not actually check that arguments match the type of their parameters.\nHowever, any good editor will tell you if you pass in the wrong type by mistake.\nStill, this is often the source of cryptic errors since it seems like Python should stop you from making this kind of mistake.\nIt is important to remember that Python will not try to convert arguments or return values according to what it sees in the header \u2013 it lets you make whatever mistakes you want!\n\n## Return\n\n```python area-function\n# Even though this says it returns a string,\n#   it will actually return an integer!\ndef area(length:int, width:int) -> str:\n    return length * width\n\n# Try running it yourself!\nprint(type(area(5, 3)))\n```\n\nWhen defining a function, you can make it return a value.\nMost functions return some kind of value.\nWe make Python return values using the \"return\" statement.\nWe describe what type of value the function returns using the arrow and a type in the header.\nBut note that it is the return statement that makes a value get returned; the header just describes what should be returned.\nLike the parameters, Python will not check that the returned value's type matches the return type in the header.\nYou are expected to make these parts match up correctly.\n\n## Calling and Printing\n\n```python calling-and-printing\ndef area(length:int, width:int) -> int:\n    return length * width\n\nprint(area(3, 4))\narea(1, 8)\nprint(area(5, 2))\n```\n\nWhen you call a function, a value is always returned.\nEven if you forget the return statement, the special value `None` will be returned.\nIf you are writing code in the console, then you will see any non-`None` values appear.\nBut if you are writing code in a regular editor, the value will not appear in the console unless you use `print`.\nWe will sometimes print the result of calling a function, but remember that printing is not necessary to call a function.\n\n## Pass\n\n```python do-nothing-function\ndef func(abc: bool) -> str:\n    pass\n\nfunc(True)\nprint(func(True))\n```\n\n\nSometimes, we want to define a function without writing its body just yet.\nWe use a special statement named `pass` to fill in the body until we're ready to write it.\nPass is a very special statement: it does absolutely nothing but take up space, telling the computer to \"pass over\" this line.\nSince we always must have a body, if we didn't put the word \"pass\" there, Python would crash with a syntax error.\n\n## Pass vs Passing\n\n* `pass`: A special Python statement that does nothing but take up space.\n* \"passing into\": A phrase coders use to describe how values are provided to a function call.\n* \"consumed by\": A phrase coders use to describe how values are used by a function definition.\n\nA somewhat confusing bit about terminology here: We talk about \"passing arguments into functions\" and the \"pass statement.\" Even though it's the same word each time, they have two different meanings.\nOne is a verb and the other is a noun.\nWe use other words for this idea of \"passing in arguments,\" saying the function \"takes in\" or \"consumes\" arguments.\n\n## Signature and Arity\n\n* Signature: The type of the function's parameters and return value\n* Arity: The number of parameters\n\nWhen we talk about the *type* of a function, we are talking about its *signature*. Much like a human signature identifies someone (but not uniquely), a signature tells you something useful about a function.\nSpecifically, you can find out how to use the function.\n\nThe signature is composed of two parts: the types of the parameters and the type of the returned value. You will say things like, \"This is a function that consumes an integer and a float, and produces a string.\"\nIn addition to saying \"consumes\", you might say \"takes in\" or \"accepts\". Besides \"produce\", you might say \"returns\" or \"gives back\".\n\nThe arity is another funny word that means \"the number of parameters\". A function with one argument has arity 1, with two arguments has arity 2, and so on.\nWe sometimes call arity 0 functions \"nullary\", arity 1 functions \"unary\", arity 2 functions \"binary\", arity 3 functions \"ternary\" - although this is largely just a formalization, rather than being something terribly important to know.\n\nImportantly, if someone points to a well-defined function, you should be able to accurately describe its signature and arity just from looking at its header. Count the number of parameters to determine the arity, and then look at the parameters types and the return type to determine the signature. If someone asks you to define a function with a particular signature, you should know how to do that as well.\n\n## Summary\n\n- You can define your own functions using the `def` keyword in Python.\n- Functions have two parts: the header and the body.\n  -  The header of a function includes the name of the function, its parameters, and its expected return type.\n  - The body of a function is a sequence of one or more statements that are executed when the function is called.\n- Functions have parameters, which are formal names given to the arguments that are passed in to calls to the function.\n- Every parameter has a name and its expected type.\n- Function names follow the same rules as variable names but should usually include verbs.\n- Function definition has several key advantages:\n  - Code reuse so that we don't have to write the same statements repeatedly.\n  - Easier to debug a chunk of code in isolation from the rest of the program.\n  - Clean decomposition to break a program down into smaller pieces without keeping the whole thing in our mind at once.\n- Once a function has been defined, the function can be called using the name of the function, parentheses, and any arguments that are needed.\n- When a function call begins, execution jumps to the header. Each argument is assigned to a parameter. Then, the body is executed one line at a time.\n- A function can return a value using a `return` statement. The `return` statement terminates the function when it is reached, and execution returns to where the function was originally called.\n- Often, the result of function calls is printed. However, the `print` function is NOT required to call a function.\n- The `pass` statement is a meaningless statement that does nothing, but it is a way to have an empty body in a function.\n- The *signature* of a function is the type of its parameters and its return value\n- The *arity* of a function is the number of parameters that the function takes.\n\n","ip_ranges":"","name":"2A3) Defining Functions Reading","on_change":"","on_eval":"","on_run":"","owner_id":1,"owner_id__email":"acbart@udel.edu","points":0,"public":true,"reviewed":false,"sample_submissions":[],"settings":"{\n  \"header\": \"Defining Functions\",\n  \"slides\": \"bakery_functions_defining.pdf\",\n  \"youtube\": {\n    \"Bart\": \"9p8PW5u3Ee0\",\n    \"Amy\": \"7jOAQvKra-A\"\n  },\n  \"video\": {\n    \"Bart\": \"https://blockpy.cis.udel.edu/videos/bakery_functions_defining-Bart.mp4\",\n    \"Amy\": \"https://blockpy.cis.udel.edu/videos/bakery_functions_defining-Amy.mp4\"\n  },\n  \"small_layout\": true\n}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_functions_defining_read","version":7},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":983,"assignment_version":7,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T16:04:46.422190+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T16:04:46.422190+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2037040,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-0791e7ca-83bf-44e8-9b50-c56091ab8592","user_id":2044700,"user_id__email":"","version":0},"success":true}
