Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 219bc69

Browse filesBrowse files
authored
Lecture Review: Restructuring Advanced Python Programming Section, Task 1 (#213)
* move content and add exercises * fix reference * fix typos * update exercise index * unfalimiar -> not familiar
1 parent de23d8e commit 219bc69
Copy full SHA for 219bc69

File tree

Expand file treeCollapse file tree

3 files changed

+176
-111
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+176
-111
lines changed
Open diff view settings
Collapse file

‎lectures/functions.md‎

Copy file name to clipboardExpand all lines: lectures/functions.md
+171-13Lines changed: 171 additions & 13 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,63 @@ means that there is no problem *passing a function as an argument to another
424424
function*---as we did above.
425425

426426

427+
(recursive_functions)=
428+
## Recursive Function Calls (Advanced)
429+
430+
```{index} single: Python; Recursion
431+
```
432+
433+
This is not something that you will use every day, but it is still useful --- you should learn it at some stage.
434+
435+
Basically, a recursive function is a function that calls itself.
436+
437+
For example, consider the problem of computing $x_t$ for some t when
438+
439+
```{math}
440+
:label: xseqdoub
441+
442+
x_{t+1} = 2 x_t, \quad x_0 = 1
443+
```
444+
445+
Obviously the answer is $2^t$.
446+
447+
We can compute this easily enough with a loop
448+
449+
```{code-cell} python3
450+
def x_loop(t):
451+
x = 1
452+
for i in range(t):
453+
x = 2 * x
454+
return x
455+
```
456+
457+
We can also use a recursive solution, as follows
458+
459+
```{code-cell} python3
460+
def x(t):
461+
if t == 0:
462+
return 1
463+
else:
464+
return 2 * x(t-1)
465+
```
466+
467+
What happens here is that each successive call uses it's own *frame* in the *stack*
468+
469+
* a frame is where the local variables of a given function call are held
470+
* stack is memory used to process function calls
471+
* a First In Last Out (FILO) queue
472+
473+
This example is somewhat contrived, since the first (iterative) solution would usually be preferred to the recursive solution.
474+
475+
We'll meet less contrived applications of recursion later on.
476+
477+
478+
(factorial_exercise)=
427479
## Exercises
428480

429-
```{exercise}
430-
:label: exercise_1
481+
```{exercise-start}
482+
:label: func_ex1
483+
```
431484

432485
Recall that $n!$ is read as "$n$ factorial" and defined as
433486
$n! = n \times (n - 1) \times \cdots \times 2 \times 1$.
@@ -452,10 +505,11 @@ For example
452505

453506
Try to use lambda expressions to define the function `f`.
454507

508+
```{exercise-end}
455509
```
456510

457-
```{solution-start} exercise_1
458-
:label: solution_1
511+
512+
```{solution-start} func_ex1
459513
:class: dropdown
460514
```
461515

@@ -498,19 +552,21 @@ factorial(2, f) # even (equivalent to factorial(5))
498552
```
499553

500554

501-
```{exercise}
502-
:label: exercise_2
555+
```{exercise-start}
556+
:label: func_ex2
557+
```
503558

504559
The [binomial random variable](https://en.wikipedia.org/wiki/Binomial_distribution) $Y \sim Bin(n, p)$ represents the number of successes in $n$ binary trials, where each trial succeeds with probability $p$.
505560

506561
Without any import besides `from numpy.random import uniform`, write a function
507562
`binomial_rv` such that `binomial_rv(n, p)` generates one draw of $Y$.
508563

509564
Hint: If $U$ is uniform on $(0, 1)$ and $p \in (0,1)$, then the expression `U < p` evaluates to `True` with probability $p$.
565+
```{exercise-end}
510566
```
511567

512-
```{solution-start} exercise_2
513-
:label: solution_2
568+
569+
```{solution-start} func_ex2
514570
:class: dropdown
515571
````
516572
@@ -532,8 +588,9 @@ binomial_rv(10, 0.5)
532588
```
533589

534590

535-
```{exercise}
536-
:label: exercise_3
591+
```{exercise-start}
592+
:label: func_ex3
593+
```
537594

538595
First, write a function that returns one realization of the following random device
539596

@@ -546,14 +603,18 @@ Second, write another function that does the same task except that the second ru
546603
- If a head occurs `k` or more times within this sequence, pay one dollar.
547604

548605
Use no import besides `from numpy.random import uniform`.
606+
607+
```{exercise-end}
549608
```
550609

551-
```{solution-start} exercise_3
552-
:label: solution_3
610+
```{solution-start} func_ex3
553611
:class: dropdown
612+
```
554613

555614
Here's a function for the first random device.
556-
```
615+
616+
617+
557618

558619
```{code-cell} python3
559620
from numpy.random import uniform
@@ -597,3 +658,100 @@ draw_new(3)
597658

598659
```{solution-end}
599660
```
661+
662+
663+
## Advanced Exercises
664+
665+
In the following exercises, we will write recursive functions together.
666+
667+
We will use more advanced syntaxes such as {any}`list comprehensions <list_comprehensions>` to test our solutions against a list of inputs.
668+
669+
If you are not familiar with these concepts, feel free to come back later.
670+
671+
672+
```{exercise-start}
673+
:label: func_ex4
674+
```
675+
676+
The Fibonacci numbers are defined by
677+
678+
```{math}
679+
:label: fib
680+
681+
x_{t+1} = x_t + x_{t-1}, \quad x_0 = 0, \; x_1 = 1
682+
```
683+
684+
The first few numbers in the sequence are $0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55$.
685+
686+
Write a function to recursively compute the $t$-th Fibonacci number for any $t$.
687+
688+
```{exercise-end}
689+
```
690+
691+
```{solution-start} func_ex4
692+
:class: dropdown
693+
```
694+
695+
Here's the standard solution
696+
697+
```{code-cell} python3
698+
def x(t):
699+
if t == 0:
700+
return 0
701+
if t == 1:
702+
return 1
703+
else:
704+
return x(t-1) + x(t-2)
705+
```
706+
707+
Let's test it
708+
709+
```{code-cell} python3
710+
print([x(i) for i in range(10)])
711+
```
712+
713+
```{solution-end}
714+
```
715+
716+
```{exercise-start}
717+
:label: func_ex5
718+
```
719+
720+
For this exercise, rewrite the function `factorial(n)` in **[exercise 1](factorial_exercise)** using recursion.
721+
722+
```{exercise-end}
723+
```
724+
725+
```{solution-start} func_ex5
726+
:class: dropdown
727+
```
728+
729+
Here's the standard solution
730+
731+
```{code-cell} python3
732+
def recursion_factorial(n):
733+
if n == 1:
734+
return n
735+
else:
736+
return n * recursion_factorial(n-1)
737+
```
738+
Here's a simplified solution
739+
740+
```{code-cell} python3
741+
def recursion_factorial_simplified(n):
742+
return n * recursion_factorial(n-1) if n != 1 else n
743+
```
744+
745+
Let's test them
746+
747+
```{code-cell} python3
748+
print([recursion_factorial(i) for i in range(1, 10)])
749+
```
750+
751+
```{code-cell} python3
752+
print([recursion_factorial_simplified(i) for i in range(1, 10)])
753+
```
754+
755+
756+
```{solution-end}
757+
```
Collapse file

‎lectures/python_advanced_features.md‎

Copy file name to clipboardExpand all lines: lectures/python_advanced_features.md
+4-97Lines changed: 4 additions & 97 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1596,105 +1596,12 @@ In summary, iterables
15961596
* avoid the need to create big lists/tuples, and
15971597
* provide a uniform interface to iteration that can be used transparently in `for` loops
15981598

1599-
(recursive_functions)=
1600-
## Recursive Function Calls
1601-
1602-
```{index} single: Python; Recursion
1603-
```
1604-
1605-
This is not something that you will use every day, but it is still useful --- you should learn it at some stage.
1606-
1607-
Basically, a recursive function is a function that calls itself.
1608-
1609-
For example, consider the problem of computing $x_t$ for some t when
1610-
1611-
```{math}
1612-
:label: xseqdoub
1613-
1614-
x_{t+1} = 2 x_t, \quad x_0 = 1
1615-
```
1616-
1617-
Obviously the answer is $2^t$.
1618-
1619-
We can compute this easily enough with a loop
1620-
1621-
```{code-cell} python3
1622-
def x_loop(t):
1623-
x = 1
1624-
for i in range(t):
1625-
x = 2 * x
1626-
return x
1627-
```
1628-
1629-
We can also use a recursive solution, as follows
1630-
1631-
```{code-cell} python3
1632-
def x(t):
1633-
if t == 0:
1634-
return 1
1635-
else:
1636-
return 2 * x(t-1)
1637-
```
1638-
1639-
What happens here is that each successive call uses it's own *frame* in the *stack*
1640-
1641-
* a frame is where the local variables of a given function call are held
1642-
* stack is memory used to process function calls
1643-
* a First In Last Out (FILO) queue
1644-
1645-
This example is somewhat contrived, since the first (iterative) solution would usually be preferred to the recursive solution.
1646-
1647-
We'll meet less contrived applications of recursion later on.
16481599

16491600
## Exercises
16501601

1651-
```{exercise-start}
1652-
:label: paf_ex1
1653-
```
1654-
1655-
The Fibonacci numbers are defined by
1656-
1657-
```{math}
1658-
:label: fib
1659-
1660-
x_{t+1} = x_t + x_{t-1}, \quad x_0 = 0, \; x_1 = 1
1661-
```
1662-
1663-
The first few numbers in the sequence are $0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55$.
1664-
1665-
Write a function to recursively compute the $t$-th Fibonacci number for any $t$.
1666-
1667-
```{exercise-end}
1668-
```
1669-
1670-
```{solution-start} paf_ex1
1671-
:class: dropdown
1672-
```
1673-
1674-
Here's the standard solution
1675-
1676-
```{code-cell} python3
1677-
def x(t):
1678-
if t == 0:
1679-
return 0
1680-
if t == 1:
1681-
return 1
1682-
else:
1683-
return x(t-1) + x(t-2)
1684-
```
1685-
1686-
Let's test it
1687-
1688-
```{code-cell} python3
1689-
print([x(i) for i in range(10)])
1690-
```
1691-
1692-
```{solution-end}
1693-
```
1694-
16951602

16961603
```{exercise-start}
1697-
:label: paf_ex2
1604+
:label: paf_ex1
16981605
```
16991606

17001607
Complete the following code, and test it using [this csv file](https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/master/source/_static/lecture_specific/python_advanced_features/test_table.csv), which we assume that you've put in your current working directory
@@ -1720,7 +1627,7 @@ for date in dates:
17201627
```{exercise-end}
17211628
```
17221629

1723-
```{solution-start} paf_ex2
1630+
```{solution-start} paf_ex1
17241631
:class: dropdown
17251632
```
17261633

@@ -1755,7 +1662,7 @@ for date in dates:
17551662

17561663

17571664
```{exercise-start}
1758-
:label: paf_ex3
1665+
:label: paf_ex2
17591666
```
17601667

17611668
Suppose we have a text file `numbers.txt` containing the following lines
@@ -1777,7 +1684,7 @@ Using `try` -- `except`, write a program to read in the contents of the file and
17771684
```
17781685

17791686

1780-
```{solution-start} paf_ex3
1687+
```{solution-start} paf_ex2
17811688
:class: dropdown
17821689
```
17831690

Collapse file

‎lectures/python_essentials.md‎

Copy file name to clipboardExpand all lines: lectures/python_essentials.md
+1-1Lines changed: 1 addition & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ letter_list = ['a', 'b', 'c']
455455
for index, letter in enumerate(letter_list):
456456
print(f"letter_list[{index}] = '{letter}'")
457457
```
458-
458+
(list_comprehensions)=
459459
### List Comprehensions
460460

461461
```{index} single: Python; List comprehension

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.