EE1021 Lecture 5 Worksheet — Dictionaries and Sets

Instructions

  • Record predictions before running the corresponding code.
  • Keep the supplied function and variable names in the submission template.
  • Return useful values from functions; do not request input inside them.
  • Complete the seven core tasks before the optional file extension.

1. From Tuples to a Dictionary

Start with Lecture 4-style records:

samples = [("S1", 4.92), ("S2", 5.08), ("S3", 4.97)]

Build a dictionary named readings that maps each sensor ID to its reading. Use tuple unpacking in a loop; do not write the finished dictionary directly. Print the result and retrieve the S2 reading.

2. Predict Dictionary State

Predict every printed result before running:

registry = {"S1": 4.90, "S2": 5.08}
registry["S1"] = 4.92
registry["S3"] = 4.97
removed = registry.pop("S2")

print(registry)
print(removed)
print("S2" in registry)

Identify which assignment adds an entry and which replaces a value.

3. Required and Optional Lookups

Given:

calibration = {"S1": 1.02, "S2": 0.99}
  1. Retrieve the required S1 factor with direct indexing.
  2. Retrieve optional S9 with get so that 1.0 is returned when absent.
  3. Demonstrate that the safe lookup does not add S9 to the dictionary.
  4. Explain when a default could hide a genuine data problem.

4. Iterate and Aggregate

Implement:

def reading_summary(readings):
    """Return (minimum_id, maximum_id, average)."""

Use items() to identify the sensor IDs with the minimum and maximum readings and values() to calculate the average. Test with:

{"S1": 4.92, "S2": 5.08, "S3": 4.97}

Expected IDs: S1 and S2. Round only when displaying the average.

5. Build a Frequency Dictionary

Given:

events = ["normal", "alarm", "normal", "calibration", "normal", "alarm"]

Build event_counts using get(event, 0) + 1. Then:

  • print every event and count using items();
  • print the most frequent event;
  • verify that the sum of all counts equals the length of events.

6. Set Relationships

registered = {"S1", "S2", "S3", "S4"}
active = {"S1", "S2", "S4", "S5"}
calibrated = {"S1", "S4"}
faulty = {"S2", "S5"}

Write and label expressions for:

  1. registered and active;
  2. active but not calibrated;
  3. registered and faulty;
  4. every known ID in registered or active;
  5. IDs appearing in exactly one of registered and active.

Also create an empty set correctly and add S9 to it.

7. Engineering Mini-Problem: Fleet Report

Implement:

def fleet_report(readings, calibrated):
    """Return a dictionary containing a sensor-fleet summary."""

The returned dictionary must contain:

  • sensor_count;
  • average_reading;
  • alarm_sensors, a set containing IDs outside 4.75–5.25 V inclusive;
  • needs_calibration, a set containing registered IDs not in calibrated.

Test with:

readings = {"S1": 4.92, "S2": 5.31, "S3": 4.60, "S4": 5.02}
calibrated = {"S1", "S4"}

The alarm set should be {“S2”, “S3”}, and the calibration set should be {“S2”, “S3”}.

Optional Extension: Count a Longer Event Log

A sensor reported these events during one shift:

events = ["normal", "normal", "alarm", "calibration", "normal", "offline",
          "alarm", "normal", "normal", "offline", "alarm", "normal"]

Reuse the counting pattern from Task 5 to build counts. Then print the event that occurred most often and how many times it occurred.

Submission Checklist

  • All seven core tasks are complete.
  • Predictions are recorded before actual results.
  • No pass or None placeholders remain.
  • Direct indexing is used only for required keys.
  • Empty sets use set(), not empty braces.
  • Dictionary and set results are clearly labelled.