[SOLVED] COMPSCI_2ME3 - Assignment 2

30.00 $

Category:

Description

5/5 - (2 votes)

   Introduction

The purpose of this software design exercise is to write a Python program that follows the given formal specification. The given specification is for simulating the physics of a scene where a shape moves through 2D space. Simulations of this sort are used for animations and video game physics.

The simulation is based on the familiar equation for Newton’s second law:

where F is the unbalanced force, m is the mass, r is the position of the body, v is the velocity of the body and a is the acceleration of the body. The motion of the body is calculated about the centre of mass (cm). Figure 1 provides an example of the possible output generated by the modules in this assignment.

Figure 1: Motion simulation for an object shown as plots of x vs t, y vs t and y vs x

For those that are interested, additional information can be found in the following papers: Physics, The Next Frontier and Physics, Part 2: Angular Effects.

As for the previous assignment, you will use doxygen, make, LaTeX and Python (version 3). In addition, this assignment will use pytest for unit testing and flake8 to verify that its pep8-inspired standard is enforced. This assignment also takes advantage of functional programming in Python.

All of your code, except for the testing files, should be documented using doxygen. Using doxygen on the testing files is optional. Your report should be written using LATEX. Your code should follow the given specification exactly. In particular, you should not add public methods or procedures that are not specified and you should not change the number or order of parameters for methods or procedures. If you need private methods or procedures, please use the Python convention of naming the files with the double underscore ( methodName ) (dunders)

For the purpose of understandability, the specification provided at the end of the assignment uses notation that is slightly different from the Hoffman and Strooper notation. Specifically the types for real and natural numbers are represented by R and N, respectively. (In this specification, the natural numbers are assumed to include 0.) Booleans are represented by B. Also, subscripts are used for indexing a sequence. For instance, xi means the same thing as x[i]. An overview of our mathematical notation and MIS templates can be found in the MIS Format document.

2.1        Installing scipy and matplotlib

This assignment uses two external modules that we have not previously installed: scipy and matplotlib. To install them on your virtual machine, do the following:

pip3 install scipy pip3 install matplotlib

2.2       Installing flake8

We will use flake8 to ensure your Python code meets the style conventions of the course. You have likely already installed flake8 on your VM or local machine. If not, you will need to install two ‘pip’ packages. This is the standard way to install packages for Python. First run the following command in your terminal:

pip –version

If the output includes ‘Python 3,’ then run the following instructions:

pip install flake8 pip install pep8-naming

If it does not, then use pip3 for the following alternate instructions.

pip3 install flake8 pip3 install pep8-naming

2.3       Running flake8

Run the following command in your A2 directory. This will inform you of the location and types of style violations. You can find more information on what each error means here: https://lintlyci.github.io/Flake8Rules/ flake8

Part 1

Step 1

Write the modules Shape.py, CircleT.py, TriangleT.py, BodyT.py, Scene.py, Plot.py following the specification given at the end of the assignment.

Step 2

Write a module (named test driver.py), using pytest, that tests the following modules: CircleT.py, TriangleT.py, BodyT.py and Scene.py. (Plot.py should be tested manually.) For Scene.py you do not have to test the getters or setters for the functions Fx and Fy. The given makefile Makefile has a rule test for running your tests. Each procedure/method should have at least one test case. Record your rationale for test case selection and the results of using this module to test the procedures in your modules. (You will submit your rationale with your report in Step 6.) Please make an effort to test normal cases, boundary cases, and exception cases. Your test program should compare the calculated output to the expected output and provide a summary of the number of test case that have passed or failed.

Testing the output of the sim method from Scene.py is made challenging because the output is sequences of real numbers. Use the following relative error formula when comparing a calculated sequence xcalc to the true solution xtrue:

(1)

Subtracting two sequences is done by subtracting corresponding elements to create a new sequence. The double vertical bars around a sequence mean taking the norm of the sequence, where the norm is a measure of the magnitude of the sequence. There are many different possible norms. The simplest is to find the maximum absolute value in the sequence. The two sequences are considered close to being equal if the left hand side of the equation is less than some small number . You are free to select a value for  that you feel is reasonable.

In testing you may want to consider some common cases, as follows:

  • The shape falling under the force of gravity in the negative y direction: Fx(t) = 0, Fy(t) = −gm, vx = 0, vy = 0.
  • Projectile or ballistics motion: Fx(t) = 0, Fy(t) = −gm, vx = v cos(θ), vy = v sin(θ) where v is the magnitude of the initial velocity and θ is the angle from the horizontal.

To get more interesting plots, you may want to experiment with conditional expressions, like that shown in test expt.py. You can run this file via the make rule (make expt).

Step 3

Test the supplied Makefile rule for doc. This rule should compile your documentation into an html and LATEX version. Along with the supplied Makefile, a doxygen configuration file is also given in your initial repo. You should not have to change these files.

 

Your CircleT.py, TriangleT.py, BodyT.py and Scene.py files will automatically be pushed to your partner’s repo. Including your name in your partner code files is optional.

Step 4

After you have received your partner’s files, temporarily replace your corresponding files with your partner’s. (You are just moving the files for the purpose of testing; you will not replace your version of the code in the git repo.) Do not initially make any modifications to any of the code. Run your test module and record the results. Your evaluation for this step does not depend on the quality of your partner’s code, but only on your discussion of the testing results. If the tests fail, for the purposes of understanding what happened, you are allowed to modify your partner’s code.

 

Shape Interface Module

Interface Module

Shape

Uses

None

Syntax

Exported Constants

None

Exported Types

None

Exported Access Programs

Routine name In Out Exceptions
cm x R
cm y R
mass R
m inert R

CircleT Module

Template Module inherits Shape

CircleT

Uses

Shape

Syntax

Exported Constants

None

Exported Types CircleT = ?

Exported Access Programs

Routine name In Out Exceptions
new CircleT xs : R, ys : R, rs : R, ms : R CircleT ValueError
cm x R
cm y R
mass R
m inert R

Semantics

State Variables

x : R y : R r : R m : R

State Invariant

r > 0 ∧ m > 0

 

new CircleT(xs,ys,rs,ms):

  • transition: x,y,r,m := xs,ys,rs,ms
  • output: out := self
  • exception: (¬(rs > 0 ∧ ms > 0) ⇒ ValueError) cm x():
  • output: out := x
  • exception: none cm y():
  • output: out := y
  • exception: none mass():
  • output: out := m
  • exception: none m inert():
  • output:
  • exception: none

TriangleT Module

Template Module inherits Shape

TriangleT

Uses

Shape

Syntax

Exported Constants

None

Exported Types TriangleT = ?

Exported Access Programs

Routine name In Out Exceptions
new TriangleT xs : R, ys : R, ss : R, ms : R TriangleT ValueError
cm x R
cm y R
mass R
m inert R

Semantics

State Variables

x : R y : R

s : R #side length (equilateral triangle)

m : R

State Invariant

s > 0 ∧ m > 0

new TriangleT(xs,ys,ss,ms):

  • transition: x,y,s,m := xs,ys,ss,ms
  • output: out := self
  • exception: (¬(ss > 0 ∧ ms > 0) ⇒ ValueError) cm x():
  • output: out := x
  • exception: none cm y():
  • output: out := y
  • exception: none mass():
  • output: out := m
  • exception: none m inert():
  • output:
  • exception: none

BodyT Module

Template Module inherits Shape

BodyT

Uses

Shape

Syntax

Exported Constants

None

Exported Types BodyT = ?

Exported Access Programs

Routine name In Out Exceptions
new BodyT xs : seq of R, ys : seq of R, ms : seq of R BodyT ValueError
cm x R
cm y R
mass R
m inert R

Semantics

State Variables

cmx : R cmy : R m : R

moment : R

State Invariant

moment ≥ 0 ∧ m > 0

new BodyT(xs,ys,ms):

  • transition:

cmx,cmy,m,moment := cm(xs,ms),cm(ys,ms),sum(ms),

mmom(xs,ys,ms) − sum(ms)(cm(xs,ms)2 + cm(ys,ms)2)

  • output: out := self
  • exception: (¬(|xs| = |ys| = |ms|) ⇒ ValueError |¬(∧µ : R|µ ms : µ > 0) ⇒

ValueError) cm x():

  • output: out := cmx
  • exception: none cm y():
  • output: out := cmy
  • exception: none mass():
  • output: out := m
  • exception: none m inert():
  • output: out := moment
  • exception: none

Local Functions sum : seq of R → R sum(ms) ≡ (+µ : R|µ ms : µ)

cm : seq of R × seq of R → R

cm(z,m) ≡ (+i : N|i ∈ [0..|ms| − 1] : zimi)/sum(m)

mmom : seq of R × seq of R × seq of R → R

mmom(x,y,m) ≡ (+i : N|i ∈ [0..|m| − 1] : mi(x2i + yi2))

 

Scene Module

Template Module

Scene

Uses

Shape, SciPy

Syntax

Exported Constants

None

Exported Types Scene = ?

Exported Access Programs

name In Out Exceptions
new Scene Shape, R → R, R → R, R, R Scene
get shape Shape
get unbal forces R → R, R → R
get init velo R, R
set shape Shape
set unbal forces R → R, R → R
set init velo R, R
sim R, N seq of R, seq of (seq [4] of R)

Semantics

State Variables

s : Shape

Fx : R → R # unbalanced force function in x dir Fy : R → R # unbalanced force function in y dir vx : R # initial velocity in x dir vy : R # initial velocity in y dir

State Invariant

None

Assumptions

None

Access Routine Semantics new Scene(

  • transition:
  • output: out := self
  • exception: None get shape():
  • output: out := s
  • exception: none get unbal forces():
  • output: out := Fx,Fy
  • exception: none get init velo():
  • output: out := vx,vy
  • exception: none set shape(s’):
  • transition: s := s0
  • exception: none set unbal forces(
  • transition:
  • exception: none

set init velo(

  • transition:
  • exception: none

sim(tfinal, nsteps):

  • output: out := t,odeint(ode,[cm x(),s.cm y(),vx,vy],t) where t = [i : N|i ∈ [0..nsteps

# for the sequence of t values the values should be in the natural ascending order for the i values

  • exception: none

Local Functions

ode : (seq [4] of R) × R → seq [4] of R

ode(w,t) ≡ [w[2],w[3],Fx(t)/s.mass(),Fy(t)/s.mass()]

Plot Module

Module

Plot

Uses

None

Syntax

Exported Constants

None

Exported Access Programs

Routine name In Out Exceptions
plot seq of (seq [4] of R), seq of R ValueError

Semantics

Environment Variables win: two dimensional sequence of coloured pixels

State Variables

None

State Invariant

None

Assumptions

None

Access Routine Semantics

plot(w,t)

  • transition: modify win so that it displays three appropriately labelled xy graphs of the data points in w showing the following plots
    1. x versus t
    2. y versus t
    3. y versus x where t is the supplied argument and
  • x = hi : N|i ∈ [0..|w| − 1] : w[i][0]i
  • y = hi : N|i ∈ [0..|w| − 1] : w[i][1]i

(We are abusing the sequence notation with the assumption that the sequence will be built in the order of increasing i values.) The plot should have the same structure as Figure 1.

  • exception: (¬(|w| = |t|) ⇒ ValueError)

2.3.1      Considerations

Implementation of Plot.py is facilitated by the matplotlib package.

SciPy Module

2.4       Module

SciPy

2.5      Uses

None

2.6       Syntax

2.6.1       Exported Access Programs

Name        In                                                            Out                                       Except.

odeint         (seq [4] of R) × R → seq [4] of R,        seq of (seq [4] of R)                ODE ERR

seq [4] of R, seq of R

2.7      Semantics

2.7.1      State Variables

None

2.7.2       Access Routine Semantics

#Solving

# Bold font is used to indicate variables that are a sequence type odeint(f, y0, t):

  • output: out := hi : N|i ∈ [0..|t| − 1] : hyo(ti),y1(ti),y2(ti),y3(ti)ii where

Z tfin

y(t) = y0 +             f(s,y(s))ds

t0

  • exception: exc := ( ODE Solver Fails ⇒ ODE ERR)

2.7.3      Considerations

This function is implemented by the Python library scipy. The syntax of odeint exactly matches what is given here. The output is a sequence of sequences. ODE ERR stands for any error that can be raised by the scipy implementation of odeint.