Skip to content
← Free FDE training guides

Free learning / 45-minute healthcare source-value lab

FHIR values: false, zero and missing are different facts

Preserve explicit Boolean false and quantity zero, then compare reported absence, conflicting choices, result status and unit identity across fourteen synthetic Device Observations.

No account needed. Use your own copy for writing and keep the original as a reference.

Engineering lab library / Run locally

Choose your next agent lab.

Start with the durable workflow reference, then choose the boundary you want to test. Open its walkthrough for setup, commands and expected observations.

Synthetic records. No provider key or model inference. Runs locally with the standard library.

  1. Start here / Python 3.11+ · Standard library

    FHIR value choices, presence, status and units

    Retain false and zero, distinguish reported and unexplained absence, and withhold unsupported source forms without invented values.

    Python 3.11+ · Standard library · Synthetic Device Observations · No network or patient data

Original LockedIn Labs workshop · 45 minutes. Python 3.11+ standard library. Start with JSON fields and the reference identity workshop. The runner reads fourteen authored FHIR R4-shaped Device Observation fixtures. No patient records, source requests, clinical measurements, database or files are used. The records use a synthetic vocabulary and a deliberately narrow consumer contract; this is not a general FHIR or profile validator.

You will preserve value presence, choice type, absence reason, status and unit identity before handing a source statement to another engineer. A successful local projection establishes no clinical interpretation, device safety, payment, source authority or permission.

1. Name the value before reading its truth

FHIR R4 is the pinned 4.0.1 resource format used here. An Observation can represent a measurement or simple assertion about a patient, device or another supported subject. This exercise uses only invented Device references. A local code names either a synthetic self-check Boolean or a cycle-duration quantity; it is not a clinical code set or published implementation guide.

value[x] in the specification denotes a choice of a concrete JSON field, such as valueBoolean or valueQuantity. It is not a literal JSON property name. Presence and value are different questions: the key valueBoolean can exist with value false; a quantity's numeric value can be zero. Neither is absent. The R4 Observation definitions describe the value choice and its relationship to the coded question.

A dataAbsentReason reports why an expected value is absent. R4's observation invariant keeps it separate from a present top-level value. A scalar JSON null is also different from an omitted property; do not replace either with a guessed number. FHIR JSON representation describes the general null/omission rules and the separate repeating-primitive exception. This fixture does not implement primitive extensions or repeating primitives.

Status describes the source result's state. The fixture admits only final for its supplied use. A valid preliminary observation can require review under that application policy. entered-in-error is an invalidating status, not a number to consume just because it is nonzero. A final marker alone establishes neither clinical correctness nor that a newer source revision does not exist.

2. Bind the source question to its expected shape

The source contract requires:

  • Literal subject reference Device/SYNTHETIC-DEVICE-1.
  • One coding with synthetic system, vocabulary version 1 and the expected code.
  • Boolean for self-check-passed, or exact seconds quantity for cycle-duration.
  • For quantities, system http://unitsofmeasure.org, code s, no comparator and a nonnegative finite number within this bounded fixture's supported range.

Display labels do not establish code or unit identity. unit: seconds cannot repair code: min. The Quantity datatype can express comparisons, such as less than a value; this exact-value consumer deliberately declines that additional meaning. These restrictions are an authored contract, not a declaration that all other FHIR forms are invalid. R4 Quantity is the primary datatype reference.

The six frames explain the runner's separate source records. They are authored instruction, not live source responses or a browser-based FHIR validator.

UNDERSTAND THE SYSTEM

A false or zero value is still present

Six authored frames explain fourteen synthetic FHIR R4 Device Observation cases. They compare an explicit presence reader with a deliberately broken truthiness shortcut. The browser does not validate a real source, measure a device or interpret clinical evidence.

FOLLOW THE WORK

Watch one example, step by step.

6 authored stepsYou control the pace
01 / EXPLORE THE PARTSControls loading · written explanations below
Direction of information or workReturn / feedback

WHAT THIS PART DOES

Original Observation

Retain the original JSON, resource id, meta.versionId and status. A result field belongs to that source record, not to an invented current clinical conclusion.

CONNECTED TO
  • Match context: Expected question
  • Retain status: Receiving boundary
Read the full worked example
  1. 01
    1 · False and zero are not missing

    In separate final records, valueBoolean false and valueQuantity.value 0 are explicit source values. The guarded reader returns supported_value with false or decimal 0. The broken or/truthiness expression labels both missing. Each record has its own coded question; a numeric zero is not a Boolean false.

    ACTUAL PRESENCE COMPARISON: False → supported Boolean · 0 s → supported quantity

  2. 02
    2 · Reported absence differs from unexplained absence

    Reported-absence has no value and supplies not-performed at dataAbsentReason.coding[0]. Unexplained-missing has neither value nor reason. The outputs are reported_absence and no_value_reported; neither supplies a negative result or an invented reason.

    TWO DISTINCT SOURCE RECORDS: not-performed ≠ reason not supplied

  3. 03
    3 · Do not normalize conflicting value shapes

    The null, multiple-value and value-plus-absence cases are withheld. False still counts as a present value, so adding an absence reason alongside it does not evade the Observation value/absence invariant. A parseable JSON object is not sufficient evidence of the required FHIR representation.

    WITHHELD SOURCE SHAPES: null · multiple choices · value and absence reason

  4. 04
    4 · A truthy number does not erase status

    Preliminary and entered-in-error each retain quantity 7 in their source JSON. The broken reader says present. The fixture withholds both: preliminary is outside its final-only use policy, while entered-in-error is an invalidating status marker. A preliminary record is not declared generally invalid FHIR.

    ACTUAL STATUS BOUNDARY: Quantity 7 retained · value not admitted

  5. 05
    5 · Preserve unit, comparator and question identity

    Seconds display text cannot override a coded min unit. A less-than comparator does not supply an exact quantity. A string 0 is not this contract's quantity, and a matching label cannot repair another subject or code. Those records remain withheld for their specific unresolved boundary.

    CONTRACT-SPECIFIC REFUSALS: Expected seconds and exact value · no silent conversion

  6. 06
    6 · Change the value without changing presence

    Change cycle-value from 0 to 1. The guarded reader supports both exact quantities, retaining each original JSON and field path; the changed fixture carries r2. The broken shortcut appears to work for 1 while still failing for 0. Source and integration owners still owe actual profile, resolution, freshness, access and interpretation evidence.

    CONTROLLED CHANGED INPUT: 0 s / r1 → 1 s / r2 · presence remains explicit

Read the connections in plain English
  1. 01
    Original Observation → Expected question

    Compare the supplied subject and coded question before interpreting a value.

  2. 02
    Expected question → Value choice presence

    The declared question fixes the expected Boolean or seconds quantity.

  3. 03
    Value choice presence → Selected source value

    A false or zero value survives because presence is a separate check.

  4. 04
    Value choice presence → Absence or refusal

    An absent value may carry a supported reason, lack one, or require refusal.

  5. 05
    Original Observation → Receiving boundary

    Do not ignore the result status or treat a final marker as proof of a real device's condition.

  6. 06
    Selected source value → Receiving boundary

    Carry the value and exact evidence path without broadening its meaning.

  7. 07
    Absence or refusal → Receiving boundary

    Name the missing evidence or unsupported contract rather than inventing a result.

Check your understanding: Can an adapter replace a missing or false-looking value with false or zero?

No. Boolean false and numeric zero are already explicit values in their own typed fields. Reported absence, unexplained missing content and withheld unsupported input remain distinct. Preserve the coded question, status, unit, field path and original record instead of inventing a source assertion.

3. Run fourteen value-presence cases

Download and read the runner. Keep an untouched reference and write predictions before viewing the output:

Code example
python3 --version
python3 fde-fhir-values.py > fhir-values-original.json
python3 fde-fhir-values.py --case quantity-value --cycle-value 1 > fhir-values-one.json

Each case preserves exact original fixture text in input_json, its independent contract, the guarded projection, a deliberately broken truthiness comparison and a source-immutability check. JSON decimals use Python Decimal when parsed; the quantity projection's decimal text is explicitly a report field, not a rewritten FHIR numeric value. No source file is uploaded or fetched.

CaseGuarded state / reasonDistinction to keep
boolean-falsesupported_value / explicit_booleanActual Boolean false remains present
quantity-valuesupported_value / explicit_quantityDefault numeric zero remains an exact seconds quantity
reported-absencereported_absence / not-performedAn explicit supported source reason, with no value
unexplained-missingno_value_reported / absence_reason_not_suppliedNo invented reason or negative result
null-valuewithheld / null_value_propertyA scalar null is not normalized into absence or false
multiple-valueswithheld / multiple_value_choicesTwo top-level value choices cannot become one guessed result
value-and-absencewithheld / value_and_absence_reasonFalse counts as a present value for this check
preliminarywithheld / status_not_admittedOutside this final-only use contract, not generally invalid FHIR
entered-in-errorwithheld / entered_in_errorPreserve the invalidating marker despite quantity 7
wrong-choicewithheld / unexpected_value_choiceString 0 is not this coded question's quantity
wrong-unitwithheld / unit_identity_mismatchDisplay seconds does not override coded minutes
quantity-comparatorwithheld / comparator_requires_policyLess-than is not an exact point value
wrong-subjectwithheld / subject_mismatchA value for another supplied Device cannot answer this question
wrong-codewithheld / coding_mismatchMatching display cannot repair another code

The broken comparison intentionally uses an or expression and a truth test. It calls false and zero missing, and calls the quantity 7 present even in the preliminary, entered-in-error or wrong-unit records. Its label is evidence of a faulty program, not a source assertion or an alternative approved interpretation.

4. Read the field path and original record together

Keep this written ledger beside your predictions:

Text example
boolean-false:
  present_value_keys: [valueBoolean]
  state: supported_value
  value: {kind: boolean, value: false}
  evidence_path: valueBoolean
  broken shortcut: missing

quantity-value, original:
  present_value_keys: [valueQuantity]
  state: supported_value
  value: {kind: quantity, decimal: "0", code: s}
  evidence_path: valueQuantity.value
  source meta.versionId: r1

reported-absence:
  state: reported_absence
  reason: not-performed
  value: null
  evidence_path: dataAbsentReason.coding[0]

unexplained-missing:
  state: no_value_reported
  reason: absence_reason_not_supplied
  value: null
  evidence_path: null

The null in the last two projections is the teaching report's own explicit lack of a selected result. It is not a null inserted into the original FHIR resource. The exact source JSON stays unchanged. A report schema and a source resource schema are different contracts.

Read interpret. It matches supplied context, records actual key presence, checks conflicting shapes and status, then either selects the expected typed field or preserves an absence/refusal reason. It never derives a result from display text. not-performed is one supported standard absence code; other reasons remain unsupported here rather than becoming guessed synonyms.

A Boolean false records the source assertion for this particular coded question. It is not a missing test, a numeric zero or a clinical diagnosis. A numeric zero retains its quantity type and seconds code; the fixture does not determine whether a real device could produce that result or what a clinician should do.

5. Change zero to one without changing the reading rule

Compare the original quantity case with fhir-values-one.json:

Code example
python3 fde-fhir-values.py --case quantity-value --cycle-value 0
python3 fde-fhir-values.py --case quantity-value --cycle-value 1
python3 fde-fhir-values.py --case value-and-absence

The guarded projection supports both zero and one. The changed fixture carries resource version r2; keep it separate from the original r1 record. Those revision labels are authored fixture context, not observed live server history. The broken shortcut appears correct for one but still loses zero. Changing test data to avoid a falsy value does not repair a presence bug.

In value-and-absence, a false Boolean still exists beside dataAbsentReason. The reader withholds the conflict rather than treating false as if the key were omitted. Similarly, string "0", Boolean false and numeric 0 are different JSON types. Do not coerce them merely because a user-facing label looks alike.

This source consumer implements one top-level value, no components, panels, primitive extensions or general profile/terminology validation. It refuses uninterpreted extension/structure fields conservatively. R4 permits richer resources; supporting them needs an agreed interpretation policy and tests. Literal subject matching is not reference resolution or device authentication. The actual source's profile, timestamps, version selection, access and permitted use remain receiving-team questions. No source request is made by this program.

6. Receive it as a healthcare source-integration pod

Rotate three roles for another run:

  • Builder: retain exact original JSON, contract, resource/vocabulary versions, status, present keys, selected field path and comparison output.
  • Receiver: change the cycle value without author takeover. Locate both explicit values, the reported absence and one withheld conflicting shape. Explain which source fact is available and which question remains unresolved.
  • Source/profile and integration owners: agree real reference resolution, coding/unit meaning, supported shapes, permitted status use, freshness and access evidence. Keep interpretation authority with the accountable team.

Each participant keeps individual evidence:

Text example
Learner / runtime / exact command:
Prediction before execution:
Original input_json / resource id and meta.versionId:
Expected subject / coded question / vocabulary version / value kind:
Observed status / present choice keys / absence reason:
Actual selected value and type / exact evidence path:
My contribution / assistance received:
Changed value / prediction / observed result:
Receiving action actually attempted / assistance:
Unresolved source/profile question / accountable owner / next bounded check:

For an authorized receiving experiment, use synthetic records and an agreed adapter/profile. Ask the next engineer to reproduce a false or zero value and withhold one unsupported form. Retain the precise remaining source evidence. A completed local exercise does not approve a clinical workflow or qualify a person to act independently in one.

7. Defend the contract in an interview

Explain: How can a false Boolean be present? Locate the actual value key, its JSON type and the evidence path, then distinguish a source absence reason.

Debug: Why can a truthy number still be withheld? Use quantity 7 under a non-admitted status, coded minutes or a comparator without confusing an application refusal with missing data.

Design: Name the source profile, exact coded question, value types, status policy, unit/comparator rules, current-source selection, reference/access checks and receiving evidence required before using an Observation in a real workflow.

Primary references checked 28 October 2026: HL7 · R4 Observation, Observation definitions, FHIR JSON, Quantity, and data absence codes. The fixtures, conservative consumer, comparisons, visual frames and receiving exercise are original instruction, not a clinical protocol or full validator.

Before you move on

Keep the evidence of your work.

  • Original and changed JSON records beside exact value/absence evidence paths.
  • Distinct presence, type, status, unit and source-contract observations.
  • An individual receiving record with source/profile and integration responsibilities.

Keep these in your own working copy. Reading this page does not save work or record completion.

Suggested next free session

Healthcare integration: keep the service identity across the handoff

Carry source identity, vocabulary versions and explicitly scoped facts into receiving handoff. This is a suggested sequence; choose the practice that addresses your current gap.

Open the next free guide

Free account

Give your practice a home.

Try a role exercise with account drafts and a downloadable worksheet. Keep the files you made in this guide in your own working copy.

Create a free learning account

Guided training · by application

Build toward a program.

Request structured lessons and a training seat. Scope, schedule, feedback arrangements and tuition are confirmed in writing before you commit.

Explore a training application
Have Academy access?

Use your existing training seat to open worked explanations and practice in the related lesson. Creating a free account does not grant a seat.

Open the related Academy lesson →
Back to top ↑