Skip to content
Snippets Groups Projects
Commit 74b73ddb authored by tuhe's avatar tuhe
Browse files

Added blok 5 for review

parent 5566611e
No related branches found
No related tags found
No related merge requests found
Showing
with 554 additions and 5 deletions
...@@ -17,8 +17,8 @@ cp/ex05 ...@@ -17,8 +17,8 @@ cp/ex05
cp/ex06 cp/ex06
cp/ex07 cp/ex07
cp/ex08 cp/ex08
cp/ex09 #cp/ex09
cp/ex10 #cp/ex10
cp/ex11 cp/ex11
cp/ex12 cp/ex12
cp/exam cp/exam
...@@ -26,5 +26,5 @@ cp/project1 ...@@ -26,5 +26,5 @@ cp/project1
# cp/project2 # cp/project2
cp/project3 cp/project3
cp/project4 cp/project4
cp/project5 #cp/project5
cp/project6 cp/project6
"""Exercises for week 9."""
"""The Rectangle-exercises 9.1-9.2."""
import matplotlib.pyplot as plt
class Point:
"""A class that represents a Point. See Section 15.1."""
class Rectangle:
"""A class that represents a Rectangle. See Section 15.3."""
def area(rectangle : Rectangle) -> float:
"""Compute the area of a Rectangle-object.
:param rectangle: A rectangle-object. Recall it has properties such as ``rectangle.width`` and ``rectangle.height``.
:return: The area of the rectangle.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Compute the area here. Try to use the debugger if you are stuck.")
return a
def make_a_rectangle(x, y, width, height):
"""Create and return a new Rectangle-object. Look at Section 15.3 to see what fields it must possess.
:param x: The x-position of the lower-left corner.
:param y: The y-position of the lower-left corner.
:param width: The width of the rectangle.
:param height: The height of the rectangle.
:return: A new Rectangle object.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Create and return a Rectangle object here.")
return rect
def split_rectangle(rectangle : Rectangle, horizontally : bool) -> list:
"""Split the rectangle object into two. Either horizontally or vertically.
For instance, if ``horizontally=True`` this function should return a list such as
``[left_rectangle, right_rectangle]``.
:param rectangle: A rectangle-object.
:param horizontally: If ``True`` the Rectangle is split horizontally otherwise vertically.
:return: A list with two Rectangle-objects.
"""
# TODO: 5 lines missing.
raise NotImplementedError("Implement function body")
return split
def plot_rectangle(rectangle: Rectangle):
"""Plot the rectangle using matplotlib.
:param rectangle: The Rectangle to plot.
"""
# TODO: 5 lines missing.
raise NotImplementedError("Implement function body")
def rectangle_inception(rectangle, n):
r"""Recursively generate a list of n+1 rectangles by applying split_rectangle n times.
Note that the list should contain n+1 non-overlapping rectangles with the same total area as the original rectangle.
The function should begin with a horizontal split.
:param rectangle: The initial rectangle to split.
:param n: How many recursive splits to apply
:return: A list of n+1 Rectangle-instances of the form ``[left, right_top, ...]``
"""
# TODO: 3 lines missing.
raise NotImplementedError("Implement function body")
return rectangles
if __name__ == "__main__":
rectangles = rectangle_inception(make_a_rectangle(0, 0, 10, 10), 10)
for r in rectangles:
plot_rectangle(r)
# Optionally: Let's save the rectangle for later:
from cp import savepdf
savepdf("rectangles.pdf") # Save your pretty rectangles for later.
plt.show()
"""Project work for week 9, classes I."""
import math
class Sin:
"""A class that represents the sinus-function, i.e. sin(x) where x can be any expression."""
class Cos:
"""A class that represents the cosine-function, i.e. cos(x) where x can be any expression."""
class Variable:
"""A class that represents a (named) variable such as ``x``, ``y``, ``x2``, etc."""
def make_symbol(symbol : str) -> Variable:
"""Create a new Variable object with the given name.
If ``v = make_symbol(x)`` then ``v.symbol`` should be the string ``"x"``.
:param symbol: The symbol this variable represents, e.g. ``"x"``.
:return: A new variable object.
"""
# TODO: 2 lines missing.
raise NotImplementedError("Implement function body")
return v
def sine(arg : object) -> Sin:
"""Create a new Sin object. The object will represent sin(arg).
In other words, if we let ``s = sine(arg), then s.arg should be equal to ``arg``. In our case,
``arg`` can be either a ``Variable``, or an object such as ``Sin``.
:param arg: The argument to sin.
:return: An object representing ``sin(arg)``.
"""
# TODO: 2 lines missing.
raise NotImplementedError("Implement function body")
return s
def cosine(arg : object) -> Cos:
"""Create a new Cos object. The object will represent cos(arg).
In other words, if we let ``s = cosine(arg), then s.arg should be equal to ``arg``. In our case,
``arg`` can be either a ``Variable``, or an object such as ``Cos``.
:param arg: The argument to cos.
:return: An object representing ``cos(arg)``.
"""
# TODO: 2 lines missing.
raise NotImplementedError("Implement function body")
return s
def format_expression(expression : object) -> str:
"""Format the given expression and return it as a string.
The expression is an object either of class Variable, Sin or Cos. The function should format it as a ``str``.
:param expression: An object to format.
:return: A string representation such as ``"cos(x)"`` or ``"sin(cos(y))"``.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
if __name__ == "__main__":
exp = sine(cosine(sine(sine(make_symbol('x')))))
print( format_expression(exp) )
# print(format_expression(exp), "evaluated in x=0 is", evaluate(exp, 0) )
pass
from sympy import sin, cos, symbols, evaluate, Symbol
evaluate_expression = sin.evalf # Get the evaluation-function. Ignore the right-hand side for now.
print_expression = sin.__str__ # Get the formatting-function. Ignore the right-hand side for now.
x = symbols('x') # Define a symbol
y = sin(cos(x))
print_expression(y)
evaluate_expression(y, subs={'x': 0})
y = sin(x)
isinstance(y, sin) # It is an instance of the sin-class
from sympy import Symbol
y.args
isinstance(y.args[0], Symbol)
y.args[0] == x
"""This file contains all the exercises relating to the Minecraft-example 9.3-9.8."""
import matplotlib.pyplot as plt
class Vector:
"""A class that represents a Vector, defined by the endpoint :math:`(x,y)`."""
def make_vector(x : float, y : float) -> Vector:
"""Create a new Vector object with end-points :math:`(x,y)`.
.. runblock:: pycon
>>> from cp.ex09.vector import make_vector
>>> v = make_vector(2,3)
>>> v.x
>>> v.y
:param x: The :math:`x`-position of the vector.
:param y: The :math:`y`-position of the vector.
:return: A Vector-object with the given end-point.
"""
# TODO: 3 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return v
def print_vector(v: Vector):
"""Print a vector object with coordinates (x,y) to the console.
The output format for a vector with coordinates :math:`x, y` should be simply ``(x, y)`` (on a single line)
:param v: A vector object instance.
"""
print(f"{(v.x, v.y)}")
def dot(v1 : Vector, v2 : Vector) -> float:
r"""Compute the dot-product of ``v1`` and ``v2``, i.e. :math:`\mathbf{v}_1 \cdot \mathbf{v}_2`.
:param v1: The first vector,
:param v2: The second vector,
:return: The dot product of ``v1`` and ``v2`` (as a ``float``)
"""
return v1.x * v2.x + v1.y * v2.y
def scale(s : float, v : Vector) -> Vector:
r"""Scale the vector :math:`\mathbf{v}` by a factor of :math:`s`.
:param s: A scalar number
:param v: A vector
:return: The vector :math:`s \mathbf{v}`.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return w
def add(v1 : Vector, v2 : Vector) -> Vector:
r"""Add the two vectors ``v1`` and ``v2`` and return the sum as a ``Vector`` object.
:param v1: The first vector,
:param v2: The second vector.
:return: Their sum :math:`\mathbf{v}_1+\mathbf{v}_2`
"""
return make_vector(v1.x + v2.x, v1.y+v2.y)
def sub(v1 : Vector, v2 : Vector) -> Vector:
r"""Subtract the two vectors ``v1`` and ``v2`` and return the difference as a ``Vector`` object.
:param v1: The first vector,
:param v2: The second vector.
:return: Their difference :math:`\mathbf{v}_1-\mathbf{v}_2`
"""
diff = add(v1, scale(-1, v2))
return diff
def hat(v):
r"""Given a ``Vector`` v1, this function returns a new vector which is orthogonal to v1 ('Tværvektoren' in Danish).
:param v: A vector :math:`\mathbf{v}`.
:return: A ``Vector`` that is orthogonal to :math:`\mathbf{v}`, i.e. :math:`\hat{\mathbf{v}}`.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return v_hat
class LineSegment:
"""A class that represents a line segment."""
def make_line_segment(p : Vector, q : Vector) -> LineSegment:
r"""Construct a ``LineSegment`` connecting the two vectors ``p`` and ``q``.
Note you have some freedom in terms of how you wish to store ``p`` and ``q`` in the ``LineSegment`` object;
i.e. you can either store ``p`` and ``q`` directly similar to the ``Vector``, or perhaps do something slightly
smarter.
:param p: The vector the line segments begins in
:param q: The line segment the vector ends in
:return: A LineSegment class representing the LineSegment.
"""
# TODO: 3 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return l
def point_on_line(l : LineSegment, t : float) -> Vector:
r"""Interpolate between the end-points of the LineSegment.
Given a line segment, the function will interpolate between the end-points using :math:`t \in [0,1]`
and return a Vector. This can be used to compute any point on the LineSegment and :math:`t=0,1` will
correspond to the end-points. The order is not important for the following problems.
:param l: A line defined by the two end-points vectors
:param t: Weighting of the two end-point in the inerpolation, :math:`t \in [0,1]`.
:return: A ``Vector`` corresponding to :math:`\mathbf{p} + (\mathbf{q}-\mathbf{p})t`.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return s
def plot_vector(v: Vector):
"""Plot a Vector using matplotlib.
:param v: Vector to plot.
"""
plt.plot(v.x, v.y, 'ro')
def plot_line(l : LineSegment):
r"""Plot a LineSegment using matplotlib.
:param l: The line segment to plot
"""
p = point_on_line(l, 0)
q = point_on_line(l, 1)
plt.plot([p.x, q.x], [p.y, q.y], 'k-')
class SquareWithPosition:
"""Corresponds to a square located in space. I.e., each corner has an :math:`(x,y)` coordinate."""
def make_square_with_position(x : float,y : float, width : float) -> SquareWithPosition:
r"""Create a ``SquareWithPosition`` instance with lower-left corner at :math:`(x,y)` and the given ``width``.
Note: It is up to you how you want to store the information in the SquareWithLocation-class. You can for instance
choose to store the four corners as ``Vector``-objects, the four sides as ``LineSegment``-objects.
:param x: :math:`x`-position of the lower-left corner
:param y: :math:`y`-position of the lower-left corner
:param width: The side-length of the rectangle
:return: A ``SquareWithLocation`` object.
"""
# TODO: 5 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return s
def intersect(l1: LineSegment, l2: LineSegment) -> Vector:
"""Get the intersection between two line segments assuming they intersects.
:param l1: First line
:param l2: Second line
:return: A ``Vector`` representing the point of intersection.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return p
def do_they_intersect(l1 : LineSegment, l2 : LineSegment) -> bool:
"""Determine if two line segments intersects.
:param l1: First line segment
:param l2: Second line segment
:return: ``True`` if the two line segments intersects, otherwise ``False``.
"""
# TODO: 3 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return is_intersecting
def square_to_lines(sq : SquareWithPosition) -> list:
"""Return a list of ``LineSegment``-objects corresponding to the four sides.
:param sq: The square
:return: A list of four sides, ``[l1, l2, l3, l4]``
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return lines
def plot_square(sq: SquareWithPosition):
"""Plot the ``SquareWithLocation`` instance.
:param sq: The square to plot
"""
# TODO: 2 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
def get_intersections(sq : SquareWithPosition, l : LineSegment) -> list:
"""Return a list of ``Vector``-objects corresponding to all intersections between the square and line segment.
:param sq: A square
:param l: A line segment
:return: A list of 0, 1, or 2 ``Vector``-objects corresponding to the intersections.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return intersections
def plot_intersections(sq : SquareWithPosition, l : LineSegment):
"""Plot all intersections between the square and line.
:param sq: A square
:param l: A line segment
"""
# TODO: 2 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
if __name__ == '__main__':
square = make_square_with_position(1,1,2)
line = make_line_segment(make_vector(-1, -1), make_vector(2, 4) )
vec = make_line_segment(make_vector(1, 1), make_vector(3, 1) )
plot_square(square)
plot_line(line)
plot_intersections(square, line)
plt.show()
"""This package represents exercise 10."""
"""Exercise 10.1: A hospital with doctors and patients."""
illnesses = {'hanging toenail': ('feets', 200),
'stepped on lego': ('feets', 100),
'headache': ('head', 100),
'toothache': ('head', 200),
}
class Person:
"""A simple class that represents a person."""
# TODO: 20 lines missing.
# TODO: 73 lines missing.
if __name__ == "__main__":
p = Person("Patricia Smith", 24, 'f') # use the __init__-method to construct the person.
print(p) # Call the str-method
"""A small example of how to use the super()-keyword."""
class Pet:
"""A basic Pet-class."""
def __init__(self, name, age):
"""Create a new Pet object.
:param name: The name of the Pet
:param age: The age of the Pet.
"""
self.name = name
self.age = age
def __str__(self):
"""
Automatically called by ``print(..)``.
:return: A string representation such as ``"Fido (3 years old)"``.
"""
return f"{self.name} ({self.age} years old)"
class SimpleCat(Pet):
"""A simple Cat-class. This example contains duplicated code."""
def __init__(self, name, age, favorite_food):
"""Construct a new Cat-object. Asides the name and age, it also has a favorite food.
:param name: The name of the cat, for instance ``'Mr. Whiskers'``
:param age: The age, for instance 3.
:param favorite_food: The favorite food, for instance ``"fish"``.
"""
self.name = name
self.age = age
self.favorite_food = favorite_food
class ImprovedCat(Pet):
"""The ImprovedCat uses super() to avoid duplicate code."""
def __init__(self, name, age, favorite_food):
"""Construct a new Cat-object. The example function similar to the one before.
:param name: The name of the cat, for instance ``'Mr. Whiskers'``
:param age: The age, for instance 3.
:param favorite_food: The favorite food, for instance ``"fish"``.
"""
super().__init__(name, age) # Call the Pet.__init__()-method.
self.favorite_food = favorite_food # We stll need to store this one.
if __name__ == "__main__":
a = SimpleCat("Mr. Whiskers", 3, "fish")
print(a)
print(a.favorite_food)
# Now let's make an improved cat.
b = SimpleCat("Mr. Super-duper whiskers", 4, "whatever you are eating")
print(b)
print(b.favorite_food)
"""Project work for week 10: A do-it-yourself sympy."""
import math
class Expression:
"""A mathematical expression. Can represent a constant `1`, a symbol such as `x`, or a function such as `sin(x)`."""
def evaluate(self, substitutions : dict) -> float:
"""Evaluate the expression and return a floating-point number.
The input argument is a dictionary which is used to evaluate all symbols. E.g. if ``substitutions = {'x': 3}``,
this means all instances of the symbolic expression ``x`` will be replaced by ``3``.
:param substitutions: A dictionary of substitutions. The keys are strings, and the values are numbers.
:return: A floating-point number this expression has been evaluated to.
"""
return 0
def differentiate(self, variable : str) -> 'Expression':
r"""Differentiate the expression with respect to the variable, specified as e.g. ``"x"``.
Note that if this expression is a function of other variables, we must use the chain-rule to recursively
differentiate the other expressions. e.g. :math:`\sin(f(x))' = \cos(f(x))f'(x)`.
:param variable: The variable we differentiate with respect to (example: ``"x"``)
:return: A class that inherits from ``Expression`` which corresponds to the derivative with respect to the given variable.
"""
return Expression()
def __str__(self) -> str:
"""Provide a string representation of the expression. The function is called automatically by ``print``.
:return: A string representation of this expression.
"""
return "Remember to implement the __str__()-function."
# TODO: 246 lines missing.
if __name__ == "__main__":
# construct some symbolic expressions
c1 = Constant(2)
c2 = Constant(3)
v = Variable('x')
# construct expression (2 * x + 3)
expr1 = Addition(Multiplication(c1, v), c2)
print(expr1)
print(expr1.differentiate("x"))
# let's evaluate this expression for x = 4
print(expr1.evaluate( {'x': 4} )) # prints 11
# let's differentiate this expression with respect to x
# it should be (2 * 1 + 0) = 2
diff_expr1 = expr1.differentiate('x')
# evaluate the derivative at x = 4
print(diff_expr1.evaluate( {'x': 2} )) # prints 2
# construct another expression (x ^ 3)
expr2 = Sin(v) # Constant(3))
# let's evaluate this expression for x = 2
print(expr2.evaluate( {'x': 2} )) # prints 8
print(expr2)
# let's differentiate this expression with respect to x
# it should be 3 * x ^ 2 which equals 3 * 2 ^ 2 = 12 at x = 2
diff_expr2 = expr2.differentiate('x')
print(diff_expr2)
print( Sin(Cos(Cos(v))).differentiate('y') )
# evaluate the derivative at x = 2
print(diff_expr2.evaluate({'x': 2})) # prints 12
# Doctor
# Person
# Patient
This diff is collapsed.
No preview for this file type
This diff is collapsed.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
"""Dummy (test) project from 02465."""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment