[SOLVED] COMPSCI_2ME3 -  Midterm Examination

30.00 $

Category:

Description

5/5 - (1 vote)

Question 1 [6 marks] Parnas advocates faking a rational design process as depicted in the figure below. The faked documentation follows these steps: Requirements (SRS) → Design (MG and MIS) → Application Implementation (code) → Verification and Validation (Unit Testing, Integration Testing, Review). How are the principles of a) abstraction and b) separation of concerns applied in a rational design process? In your answer you can refer to any aspects of the process, documentation, and/or Parnas’s principles.

[Fill in your answer below —SS]

  1. Abstraction The process of faking a rational design process is itself an abstraction. The abstraction, (information hiding), increases through application, S. Design Doc, Req. Doc. The Req. Doc is the most abstract document because it does not specify any implementation instruction, but only the requirement. The S. Design Doc (MIS, MG) is the second most abstract stage. Because in the level, some more instructions like the concept and the sytax and semantics are provided to programmer. The application is the the least abstract one, because it need to contain all code for the program to work.
    • The MG also illustrates Abstraction. In an MG, there are some typical information hiding such as Hardware Hiding, Software Hiding, and Behave hiding. And also we hide secrets in our modules. All of these show the concept of abstraction, which is achieved by information hiding. MIS is also an abstraction case. In a MIS, we do not need to show the specific implementation of the module, instead we only provide sytax, semantics, and other specification to the programmer. The process and this document is actually an abstraction because it omits unnecessary implementation details.
  2. Separation of Concerns MG illustrates Separation of Concerns, by writing MG, we decompose the whole system to different module, which provides service and secret.
    • The test process also illustrates Separation of Concerns, because instead of doing integration testing first, we use unit tests to verify the reliability of each method in a module. By doing this, we can find the flaw in a specific area.
    • Abstraction is a special case of separation of concerns. Many different models of the same entity can be produced by abstraction

Consider the specification for two modules: SeqServices and SetOfInt.

Sequence Services Library

Module

SeqServicesLibrary

Uses

None

Syntax

Exported Constants

None

Exported Types

None

Exported Access Programs

Routine name In Out Exceptions
max val seq of Z N ValueError
count Z, seq of Z N ValueError
spices seq of Z seq of string ValueError
new max val seq of Z, Z → B N ValueError

Semantics

State Variables

None

State Invariant

None

Assumptions

  • All access programs will have inputs provided that match the types given in the specification.

Access Routine Semantics max val(s)

  • output: out := |m| : N such that (m s) ∧ ∀(x : Z|x s : |m| ≥ |x|)
  • exception: (|s| = 0 ⇒ ValueError)

count(t,s)

  • output: out := +(x : Z|x s x = t : 1)
  • exception: (|s| = 0 ⇒ ValueError)

spices(s)

  • output: out := hx : Z|x s : (x ≤ 0 ⇒ “nutmeg”|True ⇒ “ginger”)i
  • exception: (|s| = 0 ⇒ ValueError) new max val(s, f)
  • output: out := max val(hx : Z|x s f(x) : xi)
  • exception: (|s| = 0 ⇒ ValueError)

Set of Integers Abstract Data Type

Template Module

SetOfInt

Uses

None

Syntax

Exported Types SetOfInt = ?

Exported Constants

None

Exported Access Programs

Routine name In Out Exceptions
new SetOfInt seq of Z SetOfInt
is member Z B
to seq seq of Z
union SetOfInt SetOfInt
diff SetOfInt SetOfInt
equals SetOfInt B

Semantics

State Variables s: set of Z

State Invariant

None

Assumptions • The SetOfInt constructor is called for each object instance before any other access routine is called for that object. The constructor can only be called once. All access programs will have inputs provided that match the types given in the specification.

Access Routine Semantics

new SetOfInt(xs):

  • transition: s := ∪(x : Z|x xs : {x})
  • output: out := self
  • exception: none is member(x):
  • output: x s
  • exception: none to seq():
  • output: out := set to seq(s)
  • exception: none

union(t):

  • output: SetOfInt(set to seq(s)||to seq())

# in case it is clearer, an alternate version of output is: SetOfInt(set to seq(s ∪ {x : Z|x t.to seq() : x}))

  • exception: none

diff(t):

  • output: SetOfInt(set to seq(s ∩ complement(to seq())))
  • exception: none

size():

  • output: |s|
  • exception: none empty():
  • output: s = ∅
  • exception: none

equals(t):

  • output: ∀(x : Z|x ∈ Z : x ∈ to seq() ↔ x s) # this means: t.to seq() = s
  • exception: none

Local Functions

set to seq : set of Z → seq of Z

set to seq(s) ≡ hx : Z|x s : xi # Return a seq of all of the elems in the set s, order does not matter

complement : seq of Z → set of Z complement(A) ≡ {x : Z|x 6∈ A : x}

Question 2 [15 marks]

[Complete Python code to match the above specification. —SS] The files you need to complete are: SeqServicesLibrary.py and SetOfInt.py. Two testing files are also provided: expt.py and test driver.py. The file expt.py is pre-populated with some simple experiments to help you see the interface in use, and do some initial test. You are free to add to this file to experiment with your work, but the file itself isn’t graded. The test driver.py is also not graded. However, you may want to create test cases to improve your confidence in your solution. The stubs of the necessary files are already available in your src folder. The code will automatically be imported into this document when the tex file is compiled. You should use the provided Makefile to test your code. You will NOT need to modify the Makefile. The given Makefile will work for make test, without errors, from the initial state of your repo. The make expt rule will also work, because all lines of code have been commented out. Uncomment lines as you complete work on each part of the modules relevant to those lines in expt.py file. The required imports are already given in the code. You should not make any modifications in the provided import statements. You should not delete the ones that are already there. Although you can solve the problem without adding any imports, if your solution requires additional imports, you can add them. As usual, the final test is whether the code runs on mills.

Any exceptions in the specification have names identical to the expected Python exceptions; your code should use exactly the exception names as given in the spec.

You do not need to worry about doxygen comments. However, you should include regular comments in the code where it would benefit from an explanation.

 

Remember, your code needs to implement the given specification so that the interface behaves as specified. This does NOT mean that the local functions need to all be implemented, or that the types used internally to the spec need to be implemented exactly as given. If you do implement any local functions, please make them private by preceding the name with double underscores.