-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclasses.tex
More file actions
347 lines (278 loc) · 14.7 KB
/
classes.tex
File metadata and controls
347 lines (278 loc) · 14.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
%\section{Introduction to classes}
Thhe topic of this chapter is programming with classes and objects. These topics
are important foundations for object-oriented programming (OOP), which is introduced later.
The topics of the exercises are covered in Chapter 8 in the book by Sundnes and
Chapter 7 in the book by Langtangen.
\begin{Problem}{\textbf{Saving information in a class}} \label{prob71}
\noindent In this problem you will create a class that holds the same type of
information as the dictionary in Problem \ref{people_dict}.
\paragraph{a)}
Create a class \pythoninline{Person} where the constructor takes name, age, and gender as arguments, and stores
them as attributes.
\paragraph{b)}
Add methods to the class for changing a persons name, age, and gender.
\paragraph{c)}
Add a method \pythoninline{__str__} that returns a string with all the information of that person. Create an instance of the class, using the
information for 'John' in the table from Problem \ref{people_dict}.
Change the name and gender of John. Print the information of the instance before and after changing.
Filename: \texttt{class\_people.py}
\end{Problem}
\begin{Problem}{\textbf{Right triangle class}}
\paragraph{a)}
Make a class \pythoninline{RightTriangle} that represents a right triangle. The constructor \pythoninline{__init__} should take two numbers $a$ and $b$ as arguments and store them as
attributes. These are the lengths of the two legs (shortest sides) that define the right triangle. The constructor should also calculate and store the hypotenuse as an attribute in the class.
Remember that the hypotenuse $c$ relates to the two short sides $a$ and $b$ by the Pythagorean Theorem:
\begin{equation*}
a^2 + b^2 = c^2
\end{equation*}
\paragraph{b)}
Make an object \pythoninline{triangle1} of the class \pythoninline{RightTriangle} with both short sides equal to 1. Make another object \pythoninline{triangle2} with sides equal 3 and 4. Check that your implementation is correct by printing the hypotenuse of both objects. Use the usual \texttt{object.variable} convention to get the hypotenuse.
\paragraph{c)}
To make a robust program, we often want to code it such that it prevents
being used in ways that does not make sense. In our case, a natural thing
to prevent is making a triangle with sides having negative length, since length is strictly positive.
Make changes to the class' constructor such that a \pythoninline{ValueError} is
raised if someone tries to make a triangle with sides of negative length.
To test that your class raises the error correctly, you can test it with the following code:
\begin{python}
def test_RightTriangle():
success = False
try:
triangle3 = RightTriangle(1,-1)
except ValueError:
success = True
assert success
\end{python}
\paragraph{d)}
Add a method \pythoninline{plot_triangle()} to your class which plots the triangle
when you call it. The corner where the two shortest sides meet should be in origin.
Side $a$ should be along the x-axis, and side b along y. In order to plot, you
might want to find out what the coordinates of each corner must be. You can use
\pythoninline{plt.axis("equal")} to make the axes of the plot of equal length so
that the triangle gets the right shape. Call the plotting method on the
instance \pythoninline{triangle2} that you created in b).
Filename: $\texttt{right\_triangle.py}$
\end{Problem}
\begin{Problem}{\textbf{Make a function class}}
In this problem you will implement a \pythoninline{class F} which represents the function
\begin{equation*}
f(x; n, m) = \sin(n x) \cos(m x).
\end{equation*}
Create the class and let $n$ and $m$ be parameters of the constructor, which must
be stored as class attributes.
Since the class represents a function, it should be a callable class. An instance
of a callable class can be called on like a function. The special method for
creating a callable class is \pythoninline{__call__(self, args)}. Implement the
special method \pythoninline{__call__(self, x)} such that it returns the value
of the function evaluated at \pythoninline{x}.
Create two different instances \pythoninline{u} and \pythoninline{v} of \pythoninline{class F}. Choose values $n$ and $m$ for both the instances. Plot the two instances \pythoninline{u} and \pythoninline{v} evaluated in $x$ against each other on the interval $x \in [0, 2 \pi]$. In other words, plot \pythoninline{u(x_values)} on the $x$-axis and \pythoninline{v(x_values)} on the $y$-axis. Make sure to have enough points on the interval to ensure that the line is smooth.
Filename: \texttt{F.py}
\end{Problem}
\begin{Problem}{\textbf{Extending the \pythoninline{BankAccountP} class}} \label{prob75}
\noindent Modify the class \pythoninline{BankAccountP} in the book to include a method \pythoninline{transfer} that transfers an amount between two accounts. The method should take an amount and the account you want to transfer to as arguments. Write a test function that checks that the methods \pythoninline{deposit}, \pythoninline{withdraw}, \pythoninline{transfer} and \pythoninline{get_balance} works properly.
Filename: \texttt{BankAccountP.py}
\end{Problem}
\newpage
\begin{Problem}{\textbf{Approximating the square root of two}} \label{prob72}
\noindent The square root of two can be represented by a so called \emph{continued fraction}
on the following form:
\begin{align*}
\sqrt(2)&= 1 + \frac{1}{1+\sqrt(2)} \\
&= 1 + \frac{1}{2+\frac{1}{1+\sqrt(2)}} \\
&= 1 + \frac{1}{2+\frac{1}{2+\frac{1}{1+\sqrt(2)}}}
\end{align*}
In this exercise we will exhibit two possibilities for approximating the number
$\sqrt(2)$.
\paragraph{a)}
Make a class \pythoninline{Square} with a method \pythoninline{approx_frac} that takes an integer $n$,
an initial value and returns the first $n$ fractions as above with initial value $x_0$. This can be done by iterating the
function
\begin{equation*}
f(x) = 1+\frac{1}{1+x}
\end{equation*}
starting at $x_0$. For $n=2$ and $x_0=1$ this gives
\begin{equation*}
f(f(x_0)) = 1 + \frac{1}{2+\frac{1}{1+1}}.
\end{equation*}
\paragraph{b)}
Another way to approximate the square is by iterating the function $f(x)=\frac{1}{2}\left(x+\frac{2}{x}\right)$.
Add a method \pythoninline{approx_iter} that takes
a number $x_0$, an integer $n$, and
returns the value of the function at $x_0$ iterated n times. For $n=2$ we would have
$f(f(x_0))$. From here on we assume for simplicity that $0.1 \leq x_0 \leq 2$.
\paragraph{c)}
Create a method that returns a nicely formatted table with
the two approximations and their difference $\epsilon$ along with the exact value for $n=1,2,5,10$.
Run the program, which approximation is best?
\paragraph{d)}
To visualize the approximation plot the exact value as a line in the plane
and the two approximations as points $(n, y_n)$, where $y_n$ is the approximation. Use $n = 1,2,5,10$.
Filename: \texttt{square\_iteration.py}
\end{Problem}
\begin{Problem}{\textbf{Tangent lines on a quadratic curve}} \label{prob73}
\noindent Consider a quadratic polynomial on the form $f(x)=x^2+bx+c$. At a point $x_0$ the
tangent line is given by $l(x)=(2x_0+b)x +C$ where $C=f(x_0)-(2x_0+b)x_0$.
\paragraph{a)}
Make a class \pythoninline{Quadratic} with a function $f(x)$ (a quadratic polynomial as above) as initial
argument. Make a method that computes the tangent at a point and returns the function
$l(x)$.
\emph{Hint: You will need to extract the coefficients $b=f(1)-f(0)-1$ and
$c=f(0)$.}
\paragraph{b)}
Create a method that plots the function along with its tangent at a point.
\paragraph{c)}
Make a method that animates the tangent line moving over the curve $f(x)$. Make
the animation for uniformly distributed x values in the interval $-5 \leq x \leq 5$.
Test the program with the function $f(x)=x^2$.
Filename: \texttt{quadratic\_tangents.py}
\end{Problem}
\begin{Problem}{\textbf{Numerical approximations of the derivative}} \label{prob74}
\noindent Let $f(x)$ be a function and $f'(x)$ its derivative. There are many ways to
approximate the derivative, for instance:
\begin{align*}
f'(x) &\approx \frac{f(x+h)-f(x)}{h}, \\
f'(x) &\approx \frac{f(x+h)-f(x-h)}{2h}, \\
f'(x) &\approx \frac{-f(x+2h)+8f(x+h)-8f(x-h)+f(x-2h)}{12h} .
\end{align*}
\paragraph{a)}
Make a class \pythoninline{Diff} with a constructor that takes a function $f$
as argument, and three methods \pythoninline{diff1}, \pythoninline{diff2},
and \pythoninline{diff3} that approximate the derivative using the above formulas.
\paragraph{b)}
Create an instance of the class \pythoninline{Diff}
using $f(x) = \sin\left( 2 \pi x \right)$. Visualise the difference
in accuracy of the three methods for computing the derivative by
plotting the approximate derivatives in the same window as the exact
derivative $f'(x) = 2 \pi \cos(2 \pi x)$. Let $x$ be on the interval
$x \in [-1, 1]$, and plot with $h = 0.9, 0.6, 0.3, 0.1$ to see how the
accuracy improves.
Filename: \texttt{class\_diff.py}
\end{Problem}
\begin{Problem}{\textbf{Visualizing functions}}
\noindent For a function $f(x)$ we can plot the graph of the function as points $(x,f(x))$.
This results in a curve in the plane. Suppose we have a function
\begin{equation*}
f(x,y)=(u(x,y),v(x,y)).
\end{equation*}
The graph of this function lives in four dimensions and is not easily visualized.
On way to visualize these functions is to instead of looking at the graph we look
at how $f$ act on points. For example, how the grid lines in the plane look
after $f$ is applied.
\paragraph{a)}
First we consider a specific function $f(x,y)=(x^2-y^2,2xy)$.
Write a program where you define the function $f$
and make a figure with $x$ and $y$ axis from -2 to 2 where you plot a number of
the grid lines in $x$ and $y$ direction in the same plot. You will need around 15 lines
in each direction. Make a another plot side-by-side in the same figure of all points
$(x^2-y^2,2xy)$ where $x$ and $y$ are the points in the first plot.
\paragraph{b)}
To make the construction more flexible, modify your program to be a class \pythoninline{Visualize} taking
a function $f(x,y)=(u(x,y),v(x,y))$ as initial argument. It should contain
a method \pythoninline{grid(self, n)} that generates two plots, one of grid lines,
and one of the image as in a).
\paragraph{c)}
We used grid lines of the plane to see how the function $f$ behaved. We could have
used any curves in the plane. Extend the class with a method \pythoninline{circ} that instead of using
points corresponding to grid lines, uses circles with expanding radii. Let the
axes go from -5 to 5 and the radii be uniformly distributed between
0 and 10 (15 circles should be sufficient). Test with the function $f(x,y)=(x^2-y^2+x+1,2xy+y)$.
The second plot should consist of circular like objects with a self-crossing.
\paragraph{d)}
Add a method \pythoninline{grid_anim} that shows an animation of the image of the
functions
\begin{equation*}
f_\epsilon(x,y)=[(1-\epsilon) x + \epsilon u(x,y), (1-\epsilon)y-\epsilon v(x,y) ]
\end{equation*}
where $\epsilon$ varies from 0 to 1.
\paragraph{e)}
Using the functions
\begin{align*}
f(x,y)=(x^2-y^2, 2xy) \quad \text{and} \quad g(x,y)=(x^2-y^2+x+1,2xy+y),
\end{align*}
test the \pythoninline{grid} and \pythoninline{grid_anim} methods on $f$, and the \pythoninline{circ} method on $g$. Use 15 gridlines
and 15 circles.
\begin{remark}
For the student familiar with complex numbers, this is exactly how one would
visualize a complex function $f(z)$. In our case we can use this for any function
$f(x,y)$, but we usually restrict ourself to look at functions corresponding to
certain complex functions, namely the differentiable ones.
\end{remark}
Filename: \texttt{plot\_functions.py}
\end{Problem}
\begin{Problem} {\textbf{A class for coordinates}}
\noindent
This exercise will focus on how to implement special methods. You will implement
the class \pythoninline{Coords}, which represents coordinates in three dimensions.
\emph{Hint: the class for complex numbers described in "A Primer on Scientific
Programming with Python", by H.P. Langtangen, is of similar nature to the class
you should implement in this problem.}
\paragraph{a)} Create the class \pythoninline{Coords}. Start by implementing the special methods \pythoninline{__init__(self, args)} and \pythoninline{__str__(self)}. The constructor
should take three parameters, $x$, $y$ and $z$. The string representation of the
class should be on the form $(x, y, z)$.
The implementation should be such that the code below works.
\begin{python}
sqrt3 = sqrt(3)
close = Coords(1/sqrt3, 1/sqrt3, 1/sqrt3)
far = Coords(3/sqrt3, 15/sqrt3, 21/sqrt3)
print(close)
print(far)
\end{python}
Output:
\begin{lstlisting}
(0.58, 0.58, 0.58)
(1.73, 8.66, 12.12)
\end{lstlisting}
\paragraph{b)} Implement the special methods \pythoninline{__len__(self)}
and \pythoninline{__abs__(self)}. The length of coordinates should always
be 3, as the coordinates will be in three dimensions. The absolute value
should yield the Euclidean norm (or the physical length in space), which
is given by
\begin{equation*}
||(x, y, z)||= \sqrt{x^2 + y^2 + z^2} .
\end{equation*}
The implementation should be such that the code below works.
\begin{python}
print(f"The class represents coordinates in {len(close)} dimensions")
print(f"The distance from the centre to the point close is {abs(close)}")
print(f"The distance from the centre to the point far is {abs(far)}")
\end{python}
Output:
\begin{lstlisting}
The class Coords represents coordinates in 3 dimensions
The distance from the centre to the point close is 1.00
The distance from the centre to the point far is 15.00
\end{lstlisting}
\paragraph{c)} Implement the special methods \pythoninline{__add__(self, other)} and \newline \pythoninline{__sub__(self, other)}. When adding or subtracting two objects of class \pythoninline{Coords}, a new object of class \pythoninline{Coords} should be returned.
The object returned when adding two coordinates should have the coordinates
\begin{equation*}
\begin{split}
x_{new} &= x_{self} + x_{other} \\
y_{new} &= y_{self} + y_{other} \\
z_{new} &= z_{self} + z_{other} ,
\end{split}
\end{equation*}
and similarly should the method for subtracting should return an object of \pythoninline{Coords} with coordinates at
\begin{equation*}
\begin{split}
x_{new} &= x_{self} - x_{other} \\
y_{new} &= y_{self} - y_{other} \\
z_{new} &= z_{self} - z_{other} ,
\end{split}
\end{equation*}
The implementation should be such that the code below works.
\begin{python}
further = close + far
print(f"The coordinates further are at {further}")
distance = abs(far - close)
print(f"The distance from far to close is {distance}")
centre = further - further
print(f"The coordinates at the centre are {centre}")
\end{python}
Output:
\begin{lstlisting}
The coordinates further are at (2.31, 9.24, 12.70)
The distance from far to close is 14.14
The coordinates at the centre are (0.00, 0.00, 0.00)
\end{lstlisting}
Filename: \texttt{Coords.py}
\end{Problem}