|
13 | 13 | "source": [ |
14 | 14 | "## Why use functions?\n", |
15 | 15 | "\n", |
16 | | - "functions are a great coding tool! They allow to setup reusable bits of code that you might need over and over. Using functions, you only have the write the code once, and, if you need to change it, only change it once. \n", |
| 16 | + "functions are a great coding tool! They allow you to set up reusable bits of code that you might need over and over. Using functions, you only have to write the code once, and if you need to change it, only change it once. \n", |
17 | 17 | "\n", |
18 | 18 | "We can create a function that writes the Fibonacci series to an arbitrary boundary:" |
19 | 19 | ] |
|
77 | 77 | "cell_type": "markdown", |
78 | 78 | "metadata": {}, |
79 | 79 | "source": [ |
80 | | - "The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or docstring. (More about docstrings can be found in the section Documentation Strings.) There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it’s good practice to include docstrings in code that you write, so make a habit of it.\n" |
| 80 | + "The first statement of the function body can optionally be a string literal; this string literal is the function's documentation string, or docstring. There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code. It's good practice to include docstrings in code that you write, so make a habit of it.\n" |
81 | 81 | ] |
82 | 82 | }, |
83 | 83 | { |
|
91 | 91 | "cell_type": "markdown", |
92 | 92 | "metadata": {}, |
93 | 93 | "source": [ |
94 | | - "The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced. In plain english, that means the variables that are formed and used within a function can only be used within the function, unless they are ```return```-ed - they are sent back.\n" |
95 | | - ] |
96 | | - }, |
97 | | - { |
98 | | - "cell_type": "markdown", |
99 | | - "metadata": {}, |
100 | | - "source": [ |
101 | | - "The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). [1] When a function calls another function, a new local symbol table is created for that call.\n" |
| 94 | + "The variables that are formed and used within a function can only be used within the function, unless they are ```return```-ed.\n", |
| 95 | + "\n", |
| 96 | + "\n", |
| 97 | + "**More detailed information**: *the execution of a function introduces a new symbol table used for the local variables of the function. all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.*\n", |
| 98 | + "\n", |
| 99 | + "*The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). Additionally, when a function calls another function, a new local symbol table is created for that call.*" |
102 | 100 | ] |
103 | 101 | }, |
104 | 102 | { |
105 | 103 | "cell_type": "markdown", |
106 | 104 | "metadata": {}, |
107 | 105 | "source": [ |
108 | | - "A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:\n" |
| 106 | + "A function definition introduces the function name, which has a ```type``` recognized by the interpreter as a user-defined function. \n", |
| 107 | + "\n", |
| 108 | + "This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism.\n" |
109 | 109 | ] |
110 | 110 | }, |
111 | 111 | { |
|
148 | 148 | "cell_type": "markdown", |
149 | 149 | "metadata": {}, |
150 | 150 | "source": [ |
151 | | - "Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a return statement do return a value, albeit a rather boring one. This value is called ```None``` (it’s a built-in name equivalent to null or not defined). Writing the value ```None``` is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using print:\n" |
| 151 | + "Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. However, even functions without a return statement do return a value, albeit a rather boring one. This value is called ```None``` (it’s a built-in name equivalent to null or not defined). Writing the value ```None``` is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using print:\n" |
152 | 152 | ] |
153 | 153 | }, |
154 | 154 | { |
|
207 | 207 | "cell_type": "markdown", |
208 | 208 | "metadata": {}, |
209 | 209 | "source": [ |
210 | | - "This example, as usual, demonstrates some new Python features:\n", |
| 210 | + "This example demonstrates some new Python features:\n", |
211 | 211 | "\n", |
212 | | - "The ```return``` statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.\n", |
| 212 | + "The ```return``` statement returns with a value from a function. ```return``` without an expression argument returns ```None```. Falling off the end of a function also returns ```None```.\n", |
213 | 213 | "\n", |
214 | 214 | "## An object oriented preview aside: <span style=\"color:red\">terminology alert!!!</span>\n", |
215 | 215 | "\n", |
216 | | - "The statement ```result.append(a)``` calls a method of the ```list``` type object instance ```result```. A method is simply a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, see Classes) The method append() shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to result = result + [a], but more efficient." |
| 216 | + "The statement ```result.append(a)``` calls a method of the ```list```-type object instance ```result```. \n", |
| 217 | + "\n", |
| 218 | + "**A method is simply a function that \"belongs\" to an object** and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. \n", |
| 219 | + "\n", |
| 220 | + "Different object types will have different methods associated with them. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods using ```Classes```).\n", |
| 221 | + "\n", |
| 222 | + "The method ```append()``` shown above is defined for ```list``` objects; it adds a new element at the end of the list. In this example it is equivalent to ```result = result + [a]```, but more efficient." |
217 | 223 | ] |
218 | 224 | }, |
219 | 225 | { |
|
222 | 228 | "source": [ |
223 | 229 | "## back to functions\n", |
224 | 230 | "\n", |
225 | | - "It is also possible to define functions with a variable number of arguments. In ```python```, there are three forms function arguments which can be combined. Each of these forms get used a lot.\n", |
| 231 | + "It is also possible to define functions with a variable number of arguments. In Python, there are **three forms of function arguments** which can be combined: **default, keyword, or positional**. Each form is used frequently.\n", |
226 | 232 | "\n", |
227 | | - "The most user-friendly form of a function argument is to specify an argument which has a default value. This creates a function that can be called with fewer arguments, but that also allows greater flexility in controlling the behavior within the function itself. \n", |
| 233 | + "The most user-friendly function argument form is to **specify an argument with a default value**. This creates a function that can be called with fewer arguments, but also allows greater flexility in controlling the behavior within the function itself. \n", |
228 | 234 | "\n", |
229 | 235 | "For example:" |
230 | 236 | ] |
|
277 | 283 | "cell_type": "markdown", |
278 | 284 | "metadata": {}, |
279 | 285 | "source": [ |
280 | | - "This function *requires* both ```T``` and ```r```. All the rest use the defaults if not explicitly passed in. The default values are evaluated at the point of function definition in the defining scope.\n", |
| 286 | + "This function *requires* both ```T``` and ```r```. All the rest use the defaults if other values are not explicitly passed in. The default values are evaluated at the point of function definition in the defining scope.\n", |
281 | 287 | "\n", |
282 | | - "Giving only mandatory arguments: `T`=100.0, `r`=300.0" |
| 288 | + "The mandatory arguments `T` and `r` can be defined based on their **position** in the function definition:" |
283 | 289 | ] |
284 | 290 | }, |
285 | 291 | { |
|
288 | 294 | "metadata": {}, |
289 | 295 | "outputs": [], |
290 | 296 | "source": [ |
| 297 | + "# T=100.0, r=300.0\n", |
291 | 298 | "thiem(100.0, 300.0)" |
292 | 299 | ] |
293 | 300 | }, |
294 | 301 | { |
295 | 302 | "cell_type": "markdown", |
296 | 303 | "metadata": {}, |
297 | 304 | "source": [ |
298 | | - "Giving one of the optional arguments using the implied position of `Q`: `T`=100.0, `r`=300.0, `Q`=500.0" |
| 305 | + "They can also be defined **explicitly by their keyword**, and thus be passed in any order." |
| 306 | + ] |
| 307 | + }, |
| 308 | + { |
| 309 | + "cell_type": "code", |
| 310 | + "execution_count": null, |
| 311 | + "metadata": {}, |
| 312 | + "outputs": [], |
| 313 | + "source": [ |
| 314 | + "# T=100.0, r=300.0\n", |
| 315 | + "thiem(r=300.0, T=100.0)" |
| 316 | + ] |
| 317 | + }, |
| 318 | + { |
| 319 | + "cell_type": "markdown", |
| 320 | + "metadata": {}, |
| 321 | + "source": [ |
| 322 | + "Passing optional argument `Q` using it's implied position in the function definition: `T`=100.0, `r`=300.0, `Q`=500.0" |
299 | 323 | ] |
300 | 324 | }, |
301 | 325 | { |
|
304 | 328 | "metadata": {}, |
305 | 329 | "outputs": [], |
306 | 330 | "source": [ |
307 | | - "thiem(100.0, 300.0, 10)" |
| 331 | + "thiem(100.0, 300.0, 500)" |
308 | 332 | ] |
309 | 333 | }, |
310 | 334 | { |
|
329 | 353 | "source": [ |
330 | 354 | "## Your turn\n", |
331 | 355 | "\n", |
332 | | - "1.) What is the thiem solution for `T`=1000.0, `r`=20.0?" |
| 356 | + "1. What is the thiem solution for `T`=1000.0, `r`=20.0?" |
333 | 357 | ] |
334 | 358 | }, |
335 | 359 | { |
|
343 | 367 | "cell_type": "markdown", |
344 | 368 | "metadata": {}, |
345 | 369 | "source": [ |
346 | | - "2.) What is the Thiem solution for `T`=1000.0, `r`=20.0, `h0`=40.0?" |
| 370 | + "2. What is the Thiem solution for `T`=1000.0, `r`=20.0, `h0`=40.0?" |
347 | 371 | ] |
348 | 372 | }, |
349 | 373 | { |
|
357 | 381 | "cell_type": "markdown", |
358 | 382 | "metadata": {}, |
359 | 383 | "source": [ |
360 | | - "3.) What is the Thiem solution for `T`=1000.0, `r`=20.0, `Q`=2000.0, `h0`=40.0" |
| 384 | + "3. What is the Thiem solution for `T`=1000.0, `r`=20.0, `Q`=2000.0, `h0`=40.0" |
361 | 385 | ] |
362 | 386 | }, |
363 | 387 | { |
|
371 | 395 | "cell_type": "markdown", |
372 | 396 | "metadata": {}, |
373 | 397 | "source": [ |
374 | | - "4.) What is the Thiem solution for `T`=1000.0, `r`=20.0, `Q`=2000.0, `h0`=40.0 if there is a lake 2000.0 units away?" |
| 398 | + "4. What is the Thiem solution for `T`=1000.0, `r`=20.0, `Q`=2000.0, `h0`=40.0 if there is a lake 2000.0 units away?" |
375 | 399 | ] |
376 | 400 | }, |
377 | 401 | { |
|
385 | 409 | "cell_type": "markdown", |
386 | 410 | "metadata": {}, |
387 | 411 | "source": [ |
388 | | - "5.) using a loop to accumulate Thiem results for `T`=1000.0, `r`=3000.0 for `Q` values ranging from 100.0 to 2000.0 by 100.0" |
| 412 | + "5. using a loop to accumulate Thiem results for `T`=1000.0, `r`=3000.0 for `Q` values ranging from 100.0 to 2000.0 by 100.0" |
389 | 413 | ] |
390 | 414 | }, |
391 | 415 | { |
|
399 | 423 | "cell_type": "markdown", |
400 | 424 | "metadata": {}, |
401 | 425 | "source": [ |
402 | | - "6.) redefine the Thiem function to take a list as the `Q` argument and return a list of ```h``` results. Call the new function ```thiem_list()```. Then call ```thiem_list()``` using the same Q as in 5.) above" |
| 426 | + "6. redefine the Thiem function to take a list as the `Q` argument and return a list of ```h``` results. Call the new function ```thiem_list()```. Then call ```thiem_list()``` using the same Q as in 5. above" |
403 | 427 | ] |
404 | 428 | }, |
405 | 429 | { |
|
430 | 454 | " h: list of head s\n", |
431 | 455 | " \"\"\"\n", |
432 | 456 | " h = []\n", |
433 | | - " # loop over all values of Q to create h list\n", |
| 457 | + " # TODO: loop over all values of Q to create h list\n", |
434 | 458 | "\n", |
435 | 459 | " return h" |
436 | 460 | ] |
|
450 | 474 | "source": [ |
451 | 475 | "# More on functions: ```lambda``` functions\n", |
452 | 476 | "\n", |
453 | | - "```lambda``` functions are a special type of function known as an \"in-line\" function. They are present in virtually all modern programming languages (not Fortran, that's not modern) and are usually high-optimized. They allow you to quickly define a simple-ish function that can only accept a single, *required* argument. The only reason to introduce them is because they appear frequently when using a python library named ```pandas``` that we will cover later." |
| 477 | + "```lambda``` functions are a special type of function known as an \"in-line\" function. They are present in virtually all modern programming languages (not Fortran, that's not modern) and are usually highly optimized. They allow you to quickly define a simple-ish function that only accepts a single, *required* argument. We're introducing them now because they appear frequently when using a python library named ```pandas``` that we will cover later." |
454 | 478 | ] |
455 | 479 | }, |
456 | 480 | { |
|
621 | 645 | "cell_type": "markdown", |
622 | 646 | "metadata": {}, |
623 | 647 | "source": [ |
624 | | - "A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module name is encountered in an import statement. [1] (They are also run if the file is executed as a script.)\n", |
| 648 | + "A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module name is encountered in an import statement. (They are also run if the file is executed as a script.)\n", |
625 | 649 | "\n", |
626 | | - "Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.\n", |
| 650 | + "Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user's global variables. On the other hand, if you know what you are doing you can touch a module's global variables with the same notation used to refer to its functions, modname.itemname.\n", |
627 | 651 | "\n", |
628 | 652 | "Modules can import other modules. It is customary but not required to place all import statements at the beginning of a module (or script, for that matter). The imported module names are placed in the importing module’s global symbol table.\n", |
629 | 653 | "\n", |
|
666 | 690 | } |
667 | 691 | ], |
668 | 692 | "metadata": { |
| 693 | + "kernelspec": { |
| 694 | + "display_name": "pyclass", |
| 695 | + "language": "python", |
| 696 | + "name": "python3" |
| 697 | + }, |
669 | 698 | "language_info": { |
670 | | - "name": "python" |
| 699 | + "codemirror_mode": { |
| 700 | + "name": "ipython", |
| 701 | + "version": 3 |
| 702 | + }, |
| 703 | + "file_extension": ".py", |
| 704 | + "mimetype": "text/x-python", |
| 705 | + "name": "python", |
| 706 | + "nbconvert_exporter": "python", |
| 707 | + "pygments_lexer": "ipython3", |
| 708 | + "version": "3.12.11" |
671 | 709 | } |
672 | 710 | }, |
673 | 711 | "nbformat": 4, |
|
0 commit comments