Python Tools for Economics Notebooks
Python Tools for Economics Notebooks
Notebooks structure
This notebook acts as an entry point for this module.
The purpose of this module is to explore the different tools we will be using in this course through
the use of Jupyter notebooks (like this one).
4 Conclusion 10
1 Introduction 12
1.1 Lecture notes example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2 Heading - level 1 12
2.1 Heading - level 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.1.1 Heading - level 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 Hypertext 13
3.1 Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4 Logical formatting 14
4.1 Inline text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.1 Itemized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.2 Numbered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.3 Nested lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6 Special formats 16
6.1 Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2 Horizontal rules (separators) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.3 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Contents 4
7 Conclusion 16
2 Basic version 44
2.1 Solving by equations by hand . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.2 Matrix formulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1 Definition 49
2 Application 49
1 Definition 53
2 Example 53
3 (Re)solution 53
3.1 Import packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.2 Input data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.3 Prepare the data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.4 Evaluate the Lorenz curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.5 Display Lorenz curve values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.6 Plot Lorenz curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.7 Evaluate the Gini coefficient . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1 Introduction 57
2 Implementation 57
3 Critical analysis 63
4 Conclusion 10
[1]: 5
[2]: _ + 8
[2]: 13
Hint: the _ sign works as a register for the last output value.
This is convenient sometimes and it is here just for reference. Notice that we will not
use this feature anymore. The purpose of showing this is just to stress the similarities
with (pocket) calculators.
[3]: 2 + 4 / 2 - 3 * 5
[3]: -11.0
A small difference is with the exponentiation that uses the operator **:
[4]: 8
Notice from above that the hash mark is the comment separator. This everything written in a
line after the # sign is considered a comment. This sign can be placed anywhere in the line.
[5]: a = 5
There are other data types, not only numbers, like strings that hold text, the text needs to be
enclose in quotes, single (') or double ("), as long as they agree:
In the case of a notebook if the last code line of a block is not assigned then its content
is printed.
[8]: b
Python is case sensitive, in variable names distinguishes between cases, i.e. a and A are different
symbols:
[9]: a = 5
A = (1 + 3**3) / 2
a, A
(1 - sqrt(3)) / (2 * 9 ** (1 / 4) - 2)
[10]: -0.5
In Jupyter, in order to allow us to more easily see the results of calculations, if the last expression
is not assigned to a variable then it will always be shown.
That is why the last result is printed even if we did not called the print function that is the
usual way to do it in Python. This is specific to Jupyter and it is related with the interactive use
philosophy of this tool.
Notice, though, that the same remarks regarding the precision of the results versus the presenta-
tion of the results applies here without any exception. This will be a meme of the course so please
remember this.
numbers = [1, 2, 3, 4, 5]
The first element in a list is at position 0 and is indexed using square brackets []:
[12]: numbers[0]
[12]: 1
This is a design choice. Sometimes it is useful and others it is not (there are cases where it helps
that the index start at zero).
In case you think that this possible confusion is only specific to Python and the last in position
-1:
[13]: numbers[-1]
[13]: 5
[14]: letters[2:4]
Note that the ranges in Python include the lower boundary but do not include the upper boundary.
So in the case above we get the elements that are in position 2 and 3, but not 4.
We can alter the contents of a list by specifying the new value for a particular position:
4 Conclusion
In this notebook we have explored both Python and Markdown.
The purpose of this exercise was two-fold: first to explore some simple calculations in Python
and also to see how text can be spread to explain what is being done.
The purpose of these notebooks is allow students to be able to test the code and to make changes
to see what changes. Remember that the best way to learn any language, human or not, is to
practice it. Remember also that you have the original notebooks available so do not be afraid to
change them.
In the next notebooks, of this module, we will explore both the Python language and Markdown
in more detail.
2 Heading - level 1 12
2.1 Heading - level 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.1.1 Heading - level 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 Hypertext 13
3.1 Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4 Logical formatting 14
4.1 Inline text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.1 Itemized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.2 Numbered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2.3 Nested lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
6 Special formats 16
6.1 Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.2 Horizontal rules (separators) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6.3 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7 Conclusion 16
1 Introduction
The purpose of this notebook is to give some examples regarding the use of Markdown in a note-
book.
The idea behind Markdown is that simply by the way as we write we are inferring some format.
Jupyter supports then Markdown by converting the Markdown from simple text to the rendered
view where the format is then seen as it is intended.
Markdown cells, like this one, even when used in the editable form show some hints regarding
the different elements. Usually that happens by the use of colors or other elements to show that the
content is using a special format.
• 1
• 2
• 3
To see how the examples look in raw text double click with the mouse over each cell. To render
the markup cell you can type Shift+Enter as you would to execute a code cell.
In order to change a cell into the editable form double click over it and it can be changed again.
2 Heading - level 1
One way to structure documents is to use heading levels, that work similarly to a hierarchy:
• Chapter;
• Section;
• Subsection;
• Subsubsection;
In order to do that we distinguish each level by the number of # (hash mark) that we use.
For the first level we use a single one, in the next level we use two, and so on.
3 Hypertext
Hypertext is the basis of the Internet content. We can link the text to some resource, either local
or on the internet.
In order to do that we use URL (Universal Resource Locator) just like those seen in the browser’s
location.
3.1 Links
The way to use links in Markdown is to use the format [description](url), where between
square brackets we get the description of the content that we are linking and between parenthesis
goes the content’s url.
Example: > In the Quantitative Economics website you can find lots of resources. This site
project intends to explore Quantitative Economics and Finance with the help of Python.
3.2 Images
Images are very similar to hypertext links. The only difference is that images are prefixed by an
exclamation mark (!). So the format is , now the text is the image caption,
that you usually get when you hoover the mouse over the image and the url can either be local or a
full URL location.
Example: This course is held at University of Porto.
Another option would have been to change the above URL with the image file location: [Link]
agens/LogotipoSI.
4 Logical formatting
Markdown is a simple way to format text that looks great on any device. It does not do anything
fancy like change the font size, color, or type - just the essentials, using keyboard symbols you
already know.
4.2 Lists
4.2.1 Itemized
• List
• List
• List
or
• List
• List
• List
4.2.2 Numbered
1. One
2. Two
3. Three
or
1) One
2) Two
3) Three
1. One
• 1.1
• 1.2
2. Two
• 2.1
1. 2.1.1
2. 2.1.2
• 2.2
• 2.3
As you can see in this example indentation implies meaning, in this case the level of indentation.
To quote a block, as an example to quote some authors we can the block quote. Lorem
ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
est laborum.
# code block
print ('3 backticks or')
print ('indent 4 spaces')
6 Special formats
6.1 Math
We can also typeset mathematical formulas, e.g.
𝐸 = 𝑚𝑐2 .
or
6.3 Tables
It is possible to typeset tables in text. Notice that we determine how the columns should be aligned
in the second row below:
7 Conclusion
The advantage of using Markdown in notebooks is that it allows us to mix text, images and code in
a single document. This is also known as literate programming.
The format of the notebooks allows to mix the documentation with the code and its output:
This notebook is just an example. To know more you can find further examples in:
ANU This is a fast-paced, hands-on introduction to scientific computing with Python, contained in
a Jupyter notebook. The main focus will be on introducing Python’s four most important scientific
libraries: NumPy, Scipy, Pandas and Matplotlib.
If you don’t know how to use this notebook you need to first work through this page.
A slower, more detailed and more systematic treatment of Python for scientific applications can
be found at [Link]. But this notebook is a good place to start for those who like to learn
by doing.
Here’s some information on the version of Python that I’m using:
print([Link])
3.14.0rc2 (main, Aug 14 2025, 00:00:00) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)]
2.3.3
[4]: type(a)
[4]: [Link]
There are also dtypes to represent complex numbers, unsigned integers, etc
On most machines, the default dtype for arrays is float64
[5]: a = [Link](3)
type(a[1])
[5]: numpy.float64
[6]: z = [Link](10)
[7]: [Link]
[7]: (10,)
Here the shape tuple has only one element, which is the length of the array (tuples with one
element end with a comma)
To give it dimension, we can change the shape attribute
For example, let’s make it a column vector
[9]: z
[9]: array([[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.]])
[10]: z = [Link](4)
[Link] = (2, 2)
z
[11]: z = [Link](3)
z
These are just garbage numbers — whatever was in those memory slots
Here’s how to make a regular gird sequence
[13]: z = [Link](3)
z
[14]: z = [Link](2)
z
[18]: z = [Link](1, 2, 5)
z
[19]: z[0] # First element --- Python sequences are zero based, like C, Java, etc.
[19]: np.float64(1.0)
[20]: np.float64(2.0)
[23]: z[0, 0]
[23]: np.int64(1)
[26]: z = [Link](2, 4, 5)
z
[28]: z[d]
[28]: array([2.5, 3. ])
[30]: [Link]()
[31]: A
[32]: [Link]()
[32]: np.float64(2.5)
[33]: [Link]()
[33]: np.int64(10)
[34]: [Link]()
[34]: np.int64(4)
[35]: [Link]()
[36]: [Link]()
[36]: np.float64(1.25)
[40]: a + b
[41]: a - b
[42]: a + 10
[43]: [Link] = 2, 2
[Link] = 2, 2
[44]: a
[45]: b
For Python ≥ 3.5 and NumPy ≥ 1.1 the @ operator also works.
[48]: a @ b
I’ll continue to use [Link] below for the benefit of those who are using older versions. But in
my opinion the @ operator is much nicer.
1.1.5 Comparisons
[50]: y[0] = 3
z == y
[52]: z > 3
1.2 Matplotlib
Matplotlib is an outstanding plotting and visualization library for Python that interacts nicely with
NumPy. Here are a few quick examples. We’ll see more below when we discuss the SciPy library.
Display figures in this browser window rather than having them open up separately:
[58]: y3 = x**3
fig, ax = [Link]() # Create axes and figure window
[Link](x, y, "b-", lw=2, alpha=0.8, label="$x^2$")
[Link](x, y3, "g-", lw=2, alpha=0.8, label="$x^3$")
[Link](loc="lower right")
1.3 SciPy
Let’s just cover some simple examples — references for further reading are below
Other methods
[61]: type(q)
[61]: [Link]._distn_infrastructure.rv_continuous_frozen
[62]: ['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__firstlineno__',
'__format__',
'__ge__',
'__getattribute__',
'__getstate__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__static_attributes__',
'__str__',
'__subclasshook__',
'__weakref__',
'a',
'args',
'b',
'cdf',
'dist',
'entropy',
'expect',
'interval',
'isf',
'kwds',
'logcdf',
'logpdf',
'logsf',
'mean',
'median',
'moment',
'pdf',
'ppf',
'random_state',
'rvs',
'sf',
'stats',
'std',
'support',
'var']
[63]: [Link](0.5)
[63]: np.float64(0.5)
[64]: [Link](0.5)
[64]: np.float64(2.4609374999999996)
[65]: [Link]()
[65]: np.float64(0.5)
n = 100
alpha, beta, sigma = 1, 2, 1.5
x = [Link](n) # n standard normals
y = alpha + beta * x + sigma * [Link](n)
beta_hat, alpha_hat, r_value, p_value, std_err = linregress(x, y)
print("gradient = {}".format(beta_hat))
print("intercept = {}".format(alpha_hat))
gradient = 1.8545073907619496
intercept = 0.9610926535807708
def f(x):
return [Link](4 * (x - 0.25)) + x + x**20 - 1
x = [Link](0, 1, 100)
[Link](x, f(x))
[Link](x, 0 * x)
[69]: from [Link] import bisect # Bisection algorithm --- slow but robust
bisect(f, 0, 1)
[69]: 0.4082935042806639
[70]: from [Link] import newton # Newton's method --- fast but less robust
[70]: np.float64(0.40829350427935673)
[71]: np.float64(0.7001700000000279)
Here we see that the algorithm gets it wrong — newton is fast but not robust
Let’s try a hybrid method
[72]: 0.40829350427936706
107 μs ± 4.22 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
116 μs ± 3.76 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
26.7 μs ± 147 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
Note that the hybrid method is robust but still quite fast…
[76]: np.float64(0.0)
[77]: 0.33333333333333337
2 −1 1
𝐴=[ ] and 𝑏=[ ]
3 0 1
[80]: A
[81]: b
[81]: array([[1.],
[1.]])
[[ 0.33333333]
[-0.33333333]]
[83]: [Link](A, x)
[83]: array([[1.],
[1.]])
[84]: [Link](A)
1.4 Pandas
Pandas is a very popular library for working with data sets. In pandas, data is held in a dataframe,
which is kind of like a spread sheet
Let’s start by writing a test data set to the present working directory, so we can read it back in
as a dataframe using pandas. We use an IPython magic to write the data from a cell to a file:
Overwriting ../data/test_data.csv
../data/test_data.csv
[92]: df = pd.read_csv("../data/test_data.csv")
[93]: df
cc cg
0 75.716805 5.578804
1 67.759026 6.720098
2 64.575551 14.072206
3 64.436451 10.266688
4 74.707624 11.658954
5 72.718710 5.726546
6 72.347054 6.032454
7 78.978740 5.108068
Let’s try that again but this time using the country as the index column
[95]: df
cc cg
country
Argentina 75.716805 5.578804
Australia 67.759026 6.720098
India 64.575551 14.072206
Israel 64.436451 10.266688
Malawi 74.707624 11.658954
South Africa 72.718710 5.726546
United States 72.347054 6.032454
Uruguay 78.978740 5.108068
cc cg
country
Argentina 75.716805 5.578804
Australia 67.759026 6.720098
India 64.575551 14.072206
Israel 64.436451 10.266688
Malawi 74.707624 11.658954
South Africa 72.718710 5.726546
United States 72.347054 6.032454
Uruguay 78.978740 5.108068
[98]: df
cc cg GDP percap
country
Argentina 75.716805 5.578804 7.903229
Australia 67.759026 6.720098 28.436433
India 64.575551 14.072206 1.717325
Israel 64.436451 10.266688 21.138673
[100]: df
cc cg GDP percap
country
Malawi 74.707624 11.658954 0.425897
India 64.575551 14.072206 1.717325
South Africa 72.718710 5.726546 5.042648
Uruguay 78.978740 5.108068 7.843971
Argentina 75.716805 5.578804 7.903229
Israel 64.436451 10.266688 21.138673
Australia 67.759026 6.720098 28.436433
United States 72.347054 6.032454 35.080382
Now we’ll plot per capital GDP using the dataframe’s plot method
1.5 Exercises
Here are two exercises. Feel free to consult documentation such as can be found here. The solutions
are below. The cell with “solution below” is mean to push them below your line of sight and save
you from temptation.
Exercise 1 Generate 10000 data points from the exponential distribution with density
Exercise 2 Using the same data set, implement maximum likelihood again, but this time pre-
tending that you don’t know the analytical expression for the maximum likelihood estimator. Set
up the log likelihood function and maximize it numerically using a routine from [Link].
1.6 Solutions
[104]: # Print some nonsense to partially hide solutions
filler_text = "solution below\n" * 25
print(filler_text)
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
solution below
Solution to Exercise 1 After checking the docs for the exponential distribution we proceed as
follows
alpha = 0.5
n = 10000
ep = expon(scale=1.0 / alpha) # scale controls the exponential parameter
x = [Link](n)
It’s well-known that the MLE of 𝛼 is 1/𝑥̄ where 𝑥̄ is the mean of the sample. Let’s check that
it is indeed close to 𝛼.
[108]: s = [Link]()
def neg_loglike(a):
"Minus the log likelihood function for exponential"
return -n * [Link](a) + a * s
[109]: np.float64(0.5029574781104512)
This is very close to the analytical value of the max likelihood estimator we got in exercise 1
2 Basic version 44
2.1 Solving by equations by hand . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.2 Matrix formulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2 Basic version
2.1 Solving by equations by hand
[1]: import numpy as np
import [Link] as plt
# demand/supply model:
# p = a - b q
# p = c + d q
a = 10
b = 0.7
c = 2
d = 0.5
[ 6. , 5.8, 5. ],
[ 7. , 5.1, 5.5],
[ 8. , 4.4, 6. ],
[ 9. , 3.7, 6.5],
[10. , 3. , 7. ],
[11. , 2.3, 7.5],
[12. , 1.6, 8. ],
[13. , 0.9, 8.5],
[14. , 0.2, 9. ]])
# evaluate equilibrium: qd = qs
qeq = (a - c) / (b + d)
peq = (a * d + b * c) / (b + d)
print(f"Equilibrium price and quantity: {peq:.3}, {qeq:.3}")
# equilibrium quantity
qeq = (a - (c + t)) / (b + d)
# equilibrium price
# (price payed by consumers and price perceived by producers)
pc = (a * d + b * (c + t)) / (b + d)
pp = ((a - t) * d + b * c) / (b + d)
2 Application 49
1 Definition
Consumer surplus, or consumers’ surplus, is the monetary gain obtained by consumers because
they are able to purchase a product for a price that is less than the highest price that they would be
willing to pay.
Producer surplus, or producers’ surplus, is the amount that producers benefit by selling at a
market price that is higher than the least that they would be willing to sell for.
Tasks:
𝑞
1. Compute the consumer surplus ∫ 𝑒 (𝐷(𝑞) − 𝑝𝑒 )𝑑𝑞.
0
𝑞
2. Compute the producer surplus ∫ 𝑒 (𝑝𝑒 − 𝑆(𝑞))𝑑𝑞.
0
2 Application
We will the supply and demand model previously explored in the previous notebook.
# demand/supply model:
# p = a - b q
# p = c + d q
a = 10
b = 0.7
c = 2
d = 0.5
# evaluate equilibrium: qd = qs
qeq = (a - c) / (b + d)
peq = (a * d + b * c) / (b + d)
# graphical representation
fig, ax = [Link]()
[Link](q, pd, "r")
[Link](q, ps, "b")
[Link](qeq, peq, "o")
[Link]([0, 10, 0, 10])
[Link]("q")
[Link]("p")
[Link]("Consumer and producer surplus");
2 Example 53
3 (Re)solution 53
3.1 Import packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.2 Input data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.3 Prepare the data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.4 Evaluate the Lorenz curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.5 Display Lorenz curve values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.6 Plot Lorenz curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.7 Evaluate the Gini coefficient . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1 Definition
The Lorenz curve and Gini coefficient are used to study the inequality in the distribution of re-
sources, usually wealth, in a given population.
For more details on this consult the Wikipedia entry on the Gini Coefficient.
2 Example
Determine the Gini coefficient and the Lorenz curve of a set of 10 firms selling turnips:
3 (Re)solution
The evaluation of the Gini coefficient involves some manipulations of the data. In particular:
• We add zero to the sold quantities because that is the initial point in the Lorenz curve;
• We operate over the sorted sells because that simplifies the evaluation of the Gini coefficient.
Below we explain the code in detail, what we are doing at each stage.
• numpy to work with numerical vectors/arrays, in order to evaluate the Lorenz curve and thus
the Gini coefficient;
• matplotlib to plot the Lorenz curve.
# We need to add the zero because that is the initial point in the Lorenz curve
data = [Link](([0], sold))
[Link]()
data
[3]: array([ 0, 3, 4, 10, 12, 12, 17, 17, 20, 25, 30])
[5]: array([[0. , 0. ],
[0.1 , 0.02 ],
[0.2 , 0.04666667],
[0.3 , 0.11333333],
[0.4 , 0.19333333],
[0.5 , 0.27333333],
[0.6 , 0.38666667],
[0.7 , 0.5 ],
[0.8 , 0.63333333],
[0.9 , 0.8 ],
[1. , 1. ]])
[Link]("%firms")
[Link]("%sales")
[Link]("Lorenz curve");
2 Implementation 57
3 Critical analysis 63
1 Introduction
Consider the Cobb-Douglas production function 𝑌 = 𝐴𝐿𝛼 𝐾 𝛽 where 𝑌 stands for production, 𝐿
labor, 𝐾 capital and the exponents 𝛼 and 𝛽 are, resp., labor and capital elasticity. For each case
draw the production function, assuming A = 1, as well as some isoquants (indifference curves):
2 Implementation
The purpose of this example is to draw the Cobb-Douglas production function for several param-
eters.
In terms of implementation this example will show how to create graphics in a different way
(using the object oriented approach).
We will give examples and hints on the usage of Python graphics for more complex cases like
the three dimensional graphics for the production function or the use of colour maps.
In order to do that we need first to import the required packages.
Since we are doing a graphical representation we need to set what should be the range where we
want to represent the function.
Sometimes the best way to this is by an trial and error approach, because it is not always obvious
what it should be interesting values. In particular notice that we do not care so much about the
units of both labour and capital.
In this case we decide that we want to draw for values of 𝐿 and 𝐾 between 0 and 3.5. We need
also to determine what is the resolution that we will draw, in this case we use an equally spaced
sequence of size 0.125 (8 points per unit).
For the first figure we set 𝛼 = 0.15 and 𝛽 = 0.25.
# Make data: generate the function values using the Cobb Douglas production function
l = [Link](0, 3.5, 0.125)
k = [Link](0, 3.5, 0.125)
L, K = [Link](l, k)
P = L**0.15 * K**0.25
[3]: [Link](l, k, P)
In the second case we repeat the code above but now for 𝛼 = 0.5 and 𝛽 = 0.5.
# Make data.
l = [Link](0, 3.5, 0.125)
k = [Link](0, 3.5, 0.125)
L, K = [Link](l, k)
P = L**0.5 * K**0.5
[5]: [Link](l, k, P)
In the third case we repeat the code above but now for 𝛼 = 0.5 and 𝛽 = 0.75.
# Make data.
l = [Link](0, 3.5, 0.125)
k = [Link](0, 3.5, 0.125)
L, K = [Link](l, k)
P = L**0.5 * K**0.75
ax.view_init(azim=-135)
[7]: [Link](l, k, P)
3 Critical analysis
This solves the problem but it is not ideal because we are repeating the same code over and over
again. And each time that we copy and pasting we risk to introduce errors.
The best strategy in this case would be to see what is common and what is different and place that
code that is common in a function. This is known as the DRY “Do not Repeat Yourself” principle.
Some possible alternatives that are left as an exercise for the reader are:
• to create a Cobb Douglas function that uses 𝛼 and 𝛽 as arguments in order to return the
production from labour and capital.
• to create a function that given a production function plots the contour nd 3-D plots.