Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# TODO: Add isort
# See: https://github.com/PyCQA/isort/pull/2122

# Real exports are test data: they must stay byte-for-byte as Lambda Feedback wrote them.
exclude: ^tests/fixtures/exports/

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
Expand Down
70 changes: 70 additions & 0 deletions tests/fixtures/exports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Real Lambda Feedback exports

Each folder here is a question set exactly as Lambda Feedback exported it. Do not edit, reformat
or re-save these files: their value is that they are what the platform really produces. To add
coverage, add another export as a new folder.

## What an export contains

```
set_<Name>.json
question_000_<Title_with_underscores>.json # 000 is the question's orderNumber
question_001_...
media/question_000_<Title>_0001.png # referenced from the questions by basename
```

JSON files are written on a single line.

## Set

`name`, `description`, `isSurvey`, `releasedAt`, `manuallyHidden`, and the visibility of final
answers, worked solutions, structured tutorials and the chatbot.

## Question

| key | meaning |
|---|---|
| `orderNumber` | position in the set, from 0; matches the filename |
| `title` | shown to students |
| `skill` | difficulty (exports use 1/3 and 2/3) |
| `guidance` | a sentence to students about the question's purpose |
| `durationLowerBound`, `durationUpperBound` | expected minutes |
| `masterContent` | markdown shared by every part: setup, data, figure |
| `publish`, `displayFinalAnswer`, `displayStructuredTutorial`, `displayWorkedSolution`, `displayChatbot` | booleans |
| `parts` | ordered from 0; students see (a), (b), ... |

## Part

| key | meaning |
|---|---|
| `content` | markdown for this part |
| `answerContent` | the final answer shown to students, markdown |
| `responseAreas` | the answer boxes; may be empty |
| `workedSolution` | `{"content": ..., "children": []}`; optional. A line containing only `---` (or `***`) splits the content into the steps of the structured tutorial |

## Response area

Every area carries the same keys: `orderNumber`, `preResponseText` and `postResponseText` (labels
either side of the box), `contentAfter` (markdown shown after the box, before the next one),
`inputSymbols`, `displayInputSymbols`, `evaluationFunctionName`, `gradeParams`, `livePreview`,
`includeInPdf`, `saveAllowed`, the feedback settings (`separateFeedback` and the colour and
prefix fields), `tests`, `cases` and `response`.

`response.responseInput` holds `responseType`, the correct `answer`, and a `config`. The pairings
in these exports:

| responseType | evaluationFunctionName | answer | notes |
|---|---|---|---|
| `MATH_SINGLE_LINE` | `symbolicEqual` | expression, e.g. `(pi/6)*rho*U**2*R**2` | `gradeParams` `{"strict_syntax": false}` |
| `NUMERIC_UNITS` | `comparePhysicalQuantities` | number and unit, e.g. `0.106 kg` | `gradeParams` includes `rtol`; `config` is null |
| `MULTIPLE_CHOICE` | `arrayEqual` | list of booleans, one per option | `config` has `single`, `options`, `randomise`; `gradeParams` null |

- `inputSymbols`: `{"symbol": "\\(\\rho\\)", "code": "rho", "aliases": [...], "isVisible": true}`. `symbol` is what students see, `code` what the evaluator reads.
- `tests`: `{"id", "payload", "expectedResponse": {"isCorrect"}}`, the author's checks of the marking.
- `cases`: `{"id", "answer", "feedback", "isCorrect", "params"}`. A response matching `answer` is shown `feedback`, and may be marked correct.

## Markdown

Maths uses `$...$` inline and `$$` on its own lines for display, rendered by KaTeX: commands
KaTeX lacks do not display (degrees written `^\circ`, for example). Images are written
`![pictureTag](question_000_Title_0001.png){ width=60% }`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"orderNumber":0,"title":"Hydraulic scale","skill":0.3333333333333333,"guidance":"This is a gentle warm up question to get into the swing of things after a long summer.","durationLowerBound":5,"durationUpperBound":10,"masterContent":"A piston of diameter $D = 0.1\\space\\mathrm{m}$ is fitted inside a U-shaped tube filled with liquid mercury (with density in $\\rho_{\\small \\mathrm{Hg}} = 13,540~\\mathrm{kg/m^{3}}$), as shown by the sketch below. The mercury rises by $h=1\\space\\mathrm{mm}$ under the weight of the piston.\n\n![pictureTag](question_000_Hydraulic_scale_0001.png){ width=30% }","publish":true,"displayFinalAnswer":true,"displayStructuredTutorial":true,"displayWorkedSolution":true,"displayChatbot":true,"parts":[{"orderNumber":0,"content":"What is the mass, $m$, of the piston?","answerContent":"$$\nm = \\boxed{0.106 \\space \\mathrm{kg}}\n$$\n","responseAreas":[{"orderNumber":0,"contentAfter":"","preResponseText":"$m=$","postResponseText":"","inputSymbols":[],"displayInputSymbols":false,"includeInPdf":false,"saveAllowed":false,"evaluationFunctionName":"comparePhysicalQuantities","livePreview":false,"gradeParams":{"rtol":0.05,"strict_syntax":false},"separateFeedback":true,"commonFeedbackColor":"#C4CDD5","correctFeedbackColor":"#22C55E","correctFeedbackPrefix":"Correct","incorrectFeedbackColor":"#ff5630","incorrectFeedbackPrefix":"Incorrect","tests":[{"id":"f3ab583b-87c3-44da-8f9b-b8cba1d03030","payload":"0.106 kg","expectedResponse":{"isCorrect":true}},{"id":"b1241594-b1b9-4f17-ba91-0bd329f45863","payload":"0.105 kilos","expectedResponse":{"isCorrect":true}},{"id":"ba11fe62-a4be-4003-bf1e-7e41bfff4ebf","payload":"0.23369 pound","expectedResponse":{"isCorrect":true}}],"cases":[{"id":"c9900536-fcd6-4cf4-8ec6-c8091574534d","answer":"0.106 kilos","feedback":"'Kilos' is ambiguous in general. Be explicit with units next time.","isCorrect":true,"params":null},{"id":"ac267f59-c6fe-4064-ba55-5758ca1e6b6c","answer":"0.106 Kg","feedback":"This is correct. Note that capital `K` is actually the SI unit for kelvin. In future use a lower case `k` for kilo (1,000).","isCorrect":true,"params":null},{"id":"e863f0dd-e4fa-4702-8fe3-a8d7319bba1f","answer":"1724 kg","feedback":"","isCorrect":false,"params":null},{"id":"921a8452-b8e3-4761-b0dd-f1a524e91cc1","answer":"13.54 Kg","feedback":"","isCorrect":false,"params":null}],"response":{"responseInput":{"responseType":"NUMERIC_UNITS","answer":"0.106 kg","config":null}}}],"workedSolution":{"content":"The weight of the piston applies a pressure $p = 4mg /(\\pi D^2)$. This pressure adds to the atmospheric pressure, so that the pressure on the mercury on the left-hand side of the tube is $p + p_{at}$. Applying the hydrostatic equations (or Bernoulli鈥檚 equations for steady, inviscid and irrotational fluids) we find:\n\n---\n\n$$\np+p_{\\mathrm{at}}=p_{\\mathrm{at}}+\\rho_\\mathrm{w}\\sigma_{\\mathrm{Hg}}gh\n$$\n\nwhere $\\sigma$ is 'specific gravity' (density relative to water).\n\n---\n\nHence:\n\n---\n\n$$\n\\begin{aligned}\\frac{4mg}{\\pi D^2} &= \\rho_\\mathrm{w} \\sigma_\\mathrm{\\small Hg} g h.\\\\m &= \\frac{\\pi}{4}\\rho_\\mathrm{w} \\sigma_\\mathrm{\\small Hg} h D^2 \\\\&= \\frac{\\pi}{4}* 1000 * 13.54 * 10^{-3} * 10^{-2} \\\\&= \\boxed{0.106\\,\\mathrm{kg}}\\end{aligned}\n$$","children":[]}},{"orderNumber":1,"content":"If this result is to be used to measure the piston's weight, what would you do to improve the accuracy of the measurement?\n","answerContent":"Selecting a fluid with a smaller specific gravity.\n","responseAreas":[],"workedSolution":{"content":"To improve the accuracy of the measurement, $D$, being fixed by the piston's size, it is best to make $h$ bigger (this is what is read), which translates in **selecting a fluid with a smaller specific gravity.**","children":[]}}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"orderNumber":1,"title":"Friction on a plate","skill":0.6666666666666666,"guidance":" This question is to refresh yourself using control volumes, which were used in ME1 and will be used often in ME2.","durationLowerBound":15,"durationUpperBound":20,"masterContent":"A fluid with density $\\rho = 800\\,\\mathrm{kg/m}^3$, flows at $U_0 = 3\\,\\mathrm{m/s}$ over a flat plate of length $L = 1\\,\\mathrm{m}$ and width $W = 1\\,\\mathrm{m}$. At the trailing edge the boundary-layer thickness is $\\delta = 25\\,\\mathrm{mm}$. Assume the velocity profile at the trailing edge to be linear (in the image shown), and the flow to be two-dimensional. \n\n![pictureTag](question_001_Friction_on_a_plate_0001.png){ width=60% }","publish":true,"displayFinalAnswer":true,"displayStructuredTutorial":true,"displayWorkedSolution":true,"displayChatbot":true,"parts":[{"orderNumber":0,"content":"Compute the mass flow rate across the top surface of the control volume (noted ''ab'' in the figure).","answerContent":"$$\n\\dot{m}= \\boxed{30 \\space \\mathrm{kg/s} \\>}\n$$","responseAreas":[{"orderNumber":0,"contentAfter":"","preResponseText":"$ \\dot{m}= $","postResponseText":"","inputSymbols":[],"displayInputSymbols":false,"includeInPdf":false,"saveAllowed":false,"evaluationFunctionName":"comparePhysicalQuantities","livePreview":false,"gradeParams":{"rtol":0.05,"strict_syntax":false},"separateFeedback":true,"commonFeedbackColor":"#C4CDD5","correctFeedbackColor":"#22C55E","correctFeedbackPrefix":"Correct","incorrectFeedbackColor":"#ff5630","incorrectFeedbackPrefix":"Incorrect","tests":[{"id":"673a7103-7930-4b11-8a62-98732b27bb5e","payload":"30 kgs-1","expectedResponse":{"isCorrect":false}}],"cases":[{"id":"092d2819-a2b5-481c-b0f9-dbfecfb176fa","answer":"30 kgs-1","feedback":"To enter a negative exponent, put the exponent in parentheses (e.g. ```kg*s^(-1)``` ). The expression ```kgs-1``` is interpreted differently and is incorrect.. ","isCorrect":false,"params":null}],"response":{"responseInput":{"responseType":"NUMERIC_UNITS","answer":"30 kg/s","config":null}}}],"workedSolution":{"content":"From mass conservation:\n\n---\n\n$\\dot{m}_{ad}=\\dot{m}_{ab}+\\dot{m}_{bc}$\n\n---\n\nThis becomes:\n\n---\n\n$\\rho W\\Large{\\int}_{\\small 0}^{\\small \\delta}\\normalsize{U_0\\space \\mathrm{d}y}=\\dot{m}_{ab}+\\rho W\\Large{\\int}_{\\small 0}^{\\small \\delta}\\normalsize{u(y)\\space\\mathrm{d}y}$\n\n---\n\nSince we know that $u(y)$ is linear, we can express it in terms of $y$ and $U_0$:\n\n---\n\n$$\nu(y)=U_0\\frac{y}{\\delta},\n$$\n\n---\n\nTherefore:\n\n$$\n\\begin{aligned}\\dot{m}_{ab}&=\\rho W U_0\\left(\\Large{\\int}_{\\small 0}^{\\small \\delta}\\normalsize{1-\\frac{y}{\\delta}\\space\\mathrm{d}y} \\right)\\\\\\dot{m}_{ab}&=\\rho W U_0\\frac{\\delta}{2},\\\\\\dot{m}_{ab}&=(800)(1)(3)\\frac{25\\times 10^{-3}}{2}.\\end{aligned}\n$$\n\n---\n\n$$\n\\dot{m}= \\boxed{30 \\space \\mathrm{kg/s} \\>}\n$$","children":[]}},{"orderNumber":1,"content":"Determine the drag force on the plate.","answerContent":"$$\nF_{\\mathrm{plate}}= \\boxed{30\\space \\mathrm{N}\\space}\n$$","responseAreas":[{"orderNumber":0,"contentAfter":"","preResponseText":"$F_D =$","postResponseText":"","inputSymbols":[],"displayInputSymbols":false,"includeInPdf":false,"saveAllowed":false,"evaluationFunctionName":"comparePhysicalQuantities","livePreview":false,"gradeParams":{"rtol":0.05,"strict_syntax":false},"separateFeedback":true,"commonFeedbackColor":"#C4CDD5","correctFeedbackColor":"#22C55E","correctFeedbackPrefix":"Correct","incorrectFeedbackColor":"#ff5630","incorrectFeedbackPrefix":"Incorrect","tests":[],"cases":[],"response":{"responseInput":{"responseType":"NUMERIC_UNITS","answer":"30 N","config":null}}}],"workedSolution":{"content":"From momentum conservation:\n\n***\n\n***\n\n$$\nF_{\\small \\mathrm{fluid}}=M_{ab}+M_{bc}-M_{ad}\n$$\n\n***\n\nSince we are calculating the horizontal resultant force, we need to consider the horizontal momentum in the section \"ab\"; this means that we ignore any vertical velocities. Since the velocity of the fluid at聽$y=\\delta$聽(i.e. at \"ab\") is always聽$U_0$, we can say:\n\n***\n\n$$\nM_{ab}=U_0\\dot{m}_{ab},\n$$\n\n***\n\nWe then also convert the other momentum flowrate terms into their mathematical forms, and proceed to find the force of the plate on the fluid, as shown below:\n\n***\n\n$$\nF_{\\mathrm{fluid}}=M_{ab}+\\rho W\\Large{\\int}_{\\small 0}^{\\small \\delta}\\normalsize{u(y)^2\\space\\mathrm{dy}}-\\rho W\\Large{\\int}_{\\small 0}^{\\small \\delta}\\normalsize{U_0^2\\space \\mathrm{dy}}\n$$\n\n***\n\n$$\nF_{\\mathrm{fluid}}=U_0\\dot{m}_{ab}+\\rho WU_0^2\\left(\\LARGE{\\int}_{\\small 0}^{\\small \\delta}\\normalsize \\frac{y^2}{\\delta^2}-1\\space\\mathrm{dy} \\right)\n$$\n\n***\n\n$$\nF_{\\mathrm{fluid}}=(3)(30)+(800)(1)(3)^2\\left[ -\\frac{2}{3}(25\\times 10^{-3})\\right]\n$$\n\n***\n\n$$\nF_{\\mathrm{fluid}}=-30 \\space \\mathrm{N}\n$$\n\n***\n\nHowever, the question asks us to find the drag force **of the fluid on the plate**, hence:\n\n***\n\n$$\nF_{\\mathrm{plate}}=-F_{\\mathrm{fluid}}\n$$\n\n***\n\n$$\nF_{\\mathrm{plate}}= \\boxed{30\\space \\mathrm{N}\\space}\n$$\n","children":[]}}]}
Loading
Loading