Grade by Grade
C. Designing Modular Programs · Modular and Object-Oriented Design

Modular and Object-Oriented Design: Unit Review

A2.1 A2.2 A2.3 C1.1 C1.2 C1.3 C1.4 A4.3 A4.4About 40 minutes
Learning goals
  • I can decompose a problem into functions, modules, classes and abstract data types, and show the design with a structure chart, CRC cards or UML.
  • I can write encapsulated classes, use inheritance, overriding and polymorphism, and explain overloading in Python and Java.
  • I can design for reuse and safely enhance existing modular code.
  • I can document code for programmers and for users to industry standards.

Words to know

modular design
Building a program from separate, cohesive, loosely coupled parts (functions, classes, modules) with clear interfaces.
object-oriented design
Designing a program as classes whose objects hold data and collaborate through methods.
reusability
How easily code can be used again, unchanged, elsewhere.

Let's review!

In this unit you learned to decompose problems into functions, modules, classes and abstract data types; to build multi-file programs with encapsulated classes, inheritance, overriding and polymorphism; to design for reuse with composition and functions as parameters; to enhance existing code safely; and to document code for programmers and users.

This review has a few questions from every lesson. Try each one, then press Show answer to check. Code in the questions uses special spaces for indentation, so type it rather than copying it.

How to use this review

Work through one or two lesson sections at a time. For every "predict the output" question, write your prediction first, then check it by running the code in Python as well as with the answer. For each question you miss, note the kind of mistake (forgot self? confused is-a and has-a? printed instead of returned? read a multiplicity backwards?) and go back to that lesson's worked examples. Finish with the 10-question quiz.

Designfunctional decompositionCRC cards, UMLabstract data typesBuildmodules and packagesclasses, encapsulationinheritance, polymorphismReuse and maintaincomposition, interfacesmodify existing codedocumentationeach new feature starts the cycle again
The unit in one picture: design the pieces, build them as modules and classes, then reuse, extend and document them, and repeat for every new feature.
Encapsulationhide the data,guard invariantsInheritanceis-a: reuse asuperclassPolymorphismone call,many formsOverridinga subclassreplaces a methodOverloadingone name, manyparameter listsA2.2: concepts that support reusable codeall resting on classes and modules (A2.1, C1.2)
The five object-oriented concepts named in expectation A2.2, built on classes and modules.

Functional Decomposition: Designing Subprograms Top-Down

1

Name two signs that a function needs to be decomposed further.

2

Which is easier to test, and why? def total(prices): return sum(prices) or def total(): print(sum(PRICES))

3

Predict: format_time(125) where format_time returns f"{s // 60}:{s % 60:02d}" for s seconds.

Modules and Packages: Programs Across Multiple Files

1

What does if __name__ == "__main__": let a module do?

2

Write the import that lets you call points_for(3) directly from the module scoring in the package carnival.

3

A student's import random fails with AttributeError. What is the likely cause?

Classes as Building Blocks: Constructors, Methods and Class Attributes

1

Predict:

class Tally:

    made = 0

    def __init__(self):

        Tally.made += 1

        self.n = 0

a = Tally()

b = Tally()

b.n += 5

print(Tally.made, a.n, b.n)

2

What is wrong with def tap(): inside a class?

3

What is the difference between a class attribute and an instance attribute?

Encapsulation: Protecting an Object's Data

1

What is an invariant? Give the SavingsAccount example.

2

With @property def balance(self): return self._balance and no setter, what does acct.balance = 0 do?

3

When is a frozen dataclass a better choice than a full class?

Object-Oriented Design with CRC Cards and UML

1

Read aloud: Course 1 ———— 0..∗ Section.

2

What goes on the right-hand side of a CRC card?

3

Filled diamond or open diamond for "a house and its rooms"? Why?

Abstract Data Types: Stacks, Queues and Dictionaries

1

Predict: push 3, push 8, pop, push 1, peek.

2

Which ADT for: (a) customer service calls answered in order (b) undo (c) looking up a postal code's city?

3

Why can client code switch from ListMap to DictMap without changes?

Inheritance as a Design Tool: Generalization and Hierarchies

1

Write the first line of a subclass constructor for Teacher(Person) that passes name and email up.

2

Is-a or has-a: (a) a Ferry and a Vehicle (b) a Shop and its Items?

3

What is the MRO of class Skis(Item)?

Overriding, Overloading and Polymorphism

1

Predict:

class Item:

    def cost(self, d):

        return 100 * d

class Helmet(Item):

    def cost(self, d):

        return super().cost(d) + 20

for g in [Item(), Helmet()]:

    print(g.cost(3))

2

What happens when Python sees two def area definitions with different parameters in one module?

3

Which special method makes sorted() work on your objects?

Designing for Reuse: Composition, Interfaces and Libraries

1

Why is composition better than inheritance for mixing 4 item kinds with 3 pricing rules?

2

What is wrong with count_if(values, is_even())?

3

What does dependency injection mean for read_int(prompt, low, high, ask=input)?

Documenting Modules, Classes and Interfaces

1

What should a module docstring contain in a multi-file program?

2

Where do you write what every subclass of an abstract class must do?

3

An override has no docstring. What does help() show for it?

User Documentation: Help Files, Manuals and Training Materials

1

Rewrite as one good instruction step: "The book command can be used for doing a booking if you want."

2

Why is argparse's --help text easy to maintain?

3

Name three things a README should answer.

Modifying Existing Modular Code to Add Features

1

What is regression testing?

2

Make this backward compatible: you need to add a today parameter to check_out(title, borrower).

3

An old test fails after your change. What should you do first?

Just for fun

Review riddle: why did the object-oriented programmer refuse to study for the unit test?

She said she had already inherited all the knowledge from her superclass. (Her teacher overrode that excuse.)

Putting It Together: A Modular Object-Oriented Project

1

In the arena project, why does Schedule.revenue() need no change when a new booking kind is added?

2

Why did version 1.1 add request() instead of changing add()?

3

What is Practice("A", 7, 10).cost() in cents?

Check your understanding

Quiz

1.

Which design keeps a function easy to test and reuse?

2.

What is the value of __name__ inside a module that has been imported (not run directly)?

3.

What does a @classmethod such as TransitCard.from_text(line) usually do?

4.

Which mechanism makes acct.balance read-only?

5.

In UML, a hollow triangle on a line points at the:

6.

Which ADT gives last-in, first-out behaviour?

7.

A Helmet subclass defines cost(self, days) to add a cleaning fee to super().cost(days). This is:

8.

Which is the best reason to favour composition here: items need any combination of several pricing rules, changeable at run time?

9.

Which is external (user) documentation?

10.

You add a feature, and an old test that used to pass now fails. This is most likely a:

For parents and teachers

How to use the results: Match each kind of mistake to the lesson to revisit.

  • Functions that print instead of return, or giant functions: Functional Decomposition.
  • ImportError, ModuleNotFoundError, files in the wrong folder, a file named after a library: Modules and Packages.
  • Forgetting self, confusing class and object, class attributes or class methods: Classes as Building Blocks.
  • Properties, underscores, invariants or dataclasses: Encapsulation.
  • Choosing classes, CRC cards, reading UML multiplicities or diamonds: Object-Oriented Design with CRC Cards and UML.
  • Mixing up stacks and queues, or interface and implementation: Abstract Data Types.
  • super().__init__ errors, or inheritance used for has-a: Inheritance as a Design Tool.
  • Overriding versus overloading, type-check chains, special methods: Overriding, Overloading and Polymorphism.
  • Too many subclasses, passing f() instead of f, untestable input code: Designing for Reuse.
  • Missing module or class docstrings, unwritten subclass contracts, no __all__: Documenting Modules, Classes and Interfaces.
  • Unclear instructions, manuals organized by code instead of tasks: User Documentation.
  • Breaking old behaviour when adding features: Modifying Existing Modular Code.
  • Difficulty combining everything: redo the activity in Putting It Together in smaller steps.

Next: the Algorithm Design and Analysis unit uses these classes and modules to study searching, sorting and recursion, and the Software Development: Managing a Team Software Project unit applies the whole design process in a team project.