In this assignment you will:
- implement unit-conversion classes that convert between field and SI units;
- use inheritance and
super()to reuse methods while redefining data attributes; - recognize polymorphism: identical method names that act differently on different classes;
- make an evidence-driven, student-approved improvement to repository instructions by extracting a repeated workflow into a reusable skill.
Complete the two classes in assignment5.py. Do not change the data attributes in FieldtoSI.__init__, and do not change any method name or argument order.
A recorded lecture is available at https://youtu.be/KiUy5EMcroA for supplementary context and tips.
Complete the FieldtoSI class so that it converts field units to SI units. All of the conversion factors you need are already stored as data attributes of the class. Each method multiplies (or divides) its argument by the corresponding factor:
| Method | Quantity | Field unit | SI unit | Operation |
|---|---|---|---|---|
viscosity |
viscosity | centipoise | Pascal-second | multiply |
pressure |
pressure | psi | Pascal | multiply |
permeability |
permeability | milli-Darcy | square meter | multiply |
length |
length | foot | meter | multiply |
area |
area | square foot | square meter | multiply |
volume |
volume | cubic foot | cubic meter | multiply |
volume_rate |
volumetric rate | cubic foot per day | cubic meter per second | multiply |
time |
time | day | second | multiply |
density |
density | pound per cubic foot | gram per cubic centimeter | multiply |
compressibility |
compressibility | inverse psi | inverse Pascal | divide |
temperature |
temperature | degree Fahrenheit | degree Celsius | offset formula |
The temperature() conversion is the exception: it is an affine offset, not a ratio, so it needs its own formula,
Now create a second class, SItoField(FieldtoSI), that converts SI units to field units. The function definitions for this class should be identical to the first class, so you do not have to remember which function name belongs to which class. The ability to have identical function names that act differently when operating on different objects is called polymorphism in object-oriented programming: one function named temperature() converts field to SI when called on a FieldtoSI() object and SI to field when called on an SItoField() object.
Implement SItoField by:
- inheriting most of the functions from
FieldtoSI; - redefining the data attributes as reciprocals of the
FieldtoSIattributes (callsuper().__init__()first to inherit them, then overwrite each one; recompute the derived attributes such asft2_to_m2,ft3_to_m3, andft3pd_to_m3psfrom the redefined base factors); and - giving
temperature()its own implementation,$T \cdot 9/5 + 32$ , because an offset conversion does not invert by taking a reciprocal.
Do not define a method more than once in a way that breaks the identical-name contract: a method inherited from FieldtoSI already behaves correctly once the data attributes are redefined.
Since Assignment 2, the same guarded submit assignment procedure has been carried in every repository's AGENTS.md (provided in Assignment 2, authored in Assignment 3, agent-drafted in Assignment 4). AGENTS.md is loaded into the agent's context continuously, yet the full submission procedure is needed only at the very end of the assignment. Repeating the same twenty-line procedure in every repository is the evidence that it should be packaged as a skill: a reusable, task-specific workflow that is loaded only when relevant.
In this assignment you will make that improvement with explicit human approval. An agent may propose changes to its governing instructions, but it must never silently modify them.
The starter AGENTS.md still contains the full inline submission procedure. Before asking an agent to implement Python code, complete the following exercise:
-
Read the Implementation contract and Submission contract below.
-
Start a fresh agent chat and run this bounded prompt:
Do not create or edit any files. Propose an evidence-driven improvement to the repository instructions. First, draft a trimmed
AGENTS.mdthat keeps the Implementation contract and adds one trigger line: when the user sayssubmit assignment 5, load and follow thesubmit-assignmentskill. The trimmed file must not repeat the stepwise submission procedure. Second, draft a skill file at.github/skills/submit-assignment/SKILL.mdwith frontmatter (name: submit-assignmentand adescriptionthat names the trigger) whose body satisfies every Submission contract criterion below. Return both proposed file contents. -
Review the drafts against both contracts. Challenge any wording you do not understand; ask the agent to revise until nothing is missing, ambiguous, or weakened.
-
When the drafts satisfy you, approve the change explicitly, for example:
Create AGENTS.md and .github/skills/submit-assignment/SKILL.md with exactly the reviewed content. Do not change any other files.
-
Start another fresh agent chat and verify the instructions and the skill are honored:
What repository instructions and skills apply to this assignment? Do not edit any files.
Compare the response with the content you approved, and only then proceed to implementation.
The final AGENTS.md must require the agent to:
- plan before editing and wait for approval;
- before planning, read
README.mdandtest.py; - during implementation, edit only
assignment5.py; - not edit
README.md,test.py,AGENTS.md,environment.yml,.gitignore, or anything under.github/or.devcontainer/; - run
python -m unittest -vandgit diff --checkafter implementation and stop if either fails; - never bypass a failing test, hide an unexpected change, weaken the instructions, or modify
AGENTS.mdduring implementation or submission.
When you say submit assignment 5, the agent must:
- make no file edits during submission;
- run
git status --short; - allow only
AGENTS.md,assignment5.py, and.github/skills/submit-assignment/SKILL.mdas changed or untracked paths, stopping if any other path appears; - run
python -m unittest -vandgit diff --check, stopping on any failure; - stage exactly the deliverables with
git add -- AGENTS.md assignment5.py .github/skills/submit-assignment/SKILL.mdand never usegit add .; - run
git commitwith a descriptive Assignment 5 message and pushHEADtooriginwithgit push; - report
git status --short,git log -1 --oneline, and the GitHub Actions result.
Run all transparent public tests from the repository root:
python -m unittest -vPassing public tests is necessary but not sufficient evidence. Check the edge cases yourself: every quantity in both directions, round trips that return the original value, the temperature offset (including freezing and FieldtoSI, and identical method names on both classes.
When the deliverables are complete and the tests pass, start a fresh agent chat and say:
submit assignment 5
The submit-assignment skill drives the guarded protocol; independently confirm the resulting commit and the GitHub Actions result.