S1Q1 · Traffic Signal Action¶
⚡ Quick Reference
Function: traffic_signal(vehicle_type, signal, emergency) -> str
Core idea: Emergency ambulance check first, then branch on signal colour.
def traffic_signal(vehicle_type, signal, emergency):
if emergency and vehicle_type == "ambulance":
return "Proceed Carefully"
if signal == "red": return "Stop"
if signal == "yellow": return "Slow Down"
if signal == "green": return "Cross" if vehicle_type == "pedestrian" else "Go"
return "Invalid Signal"
Key rules:
- Emergency ambulance overrides the signal entirely
- "green" has two outcomes depending on vehicle_type
- Any signal other than the three valid ones returns "Invalid Signal"
Problem Statement¶
Problem
Write a function traffic_signal(vehicle_type, signal, emergency) that decides what action a road user should take based on their type and the current signal.
- If
emergencyisTrueandvehicle_typeis"ambulance"→ return"Proceed Carefully" - Otherwise, decide based on
signal:"red"→"Stop""yellow"→"Slow Down""green"→"Cross"ifvehicle_type == "pedestrian", else"Go"
- Any other
signalvalue →"Invalid Signal"
Examples:
traffic_signal("car", "red", False)
"Stop"
traffic_signal("pedestrian", "green", False)
"Cross"
traffic_signal("ambulance", "red", True)
"Proceed Carefully"
Understanding the problem¶
The function has two decision layers:
- Emergency override -- checked first, regardless of signal
- Signal branch -- only reached when the override doesn't apply
A common mistake is to check the signal first and handle emergency inside the "red" branch. That breaks the case where an ambulance is on "green" during an emergency.
Order of checks matters
The emergency ambulance condition must come before the signal checks. If you nest it inside the "red" branch, traffic_signal("ambulance", "green", True) would wrongly return "Go" instead of "Proceed Carefully".
Tracing the four examples:
vehicle_type |
signal |
emergency |
Path taken | Result |
|---|---|---|---|---|
"car" |
"red" |
False |
emergency check fails → signal == "red" | "Stop" |
"bike" |
"yellow" |
False |
emergency check fails → signal == "yellow" | "Slow Down" |
"pedestrian" |
"green" |
False |
emergency check fails → signal == "green" → pedestrian | "Cross" |
"ambulance" |
"red" |
True |
emergency == True and ambulance → override | "Proceed Carefully" |
Solution approaches¶
def traffic_signal(vehicle_type: str, signal: str, emergency: bool) -> str:
# Layer 1: emergency override
if emergency and vehicle_type == "ambulance":
return "Proceed Carefully"
# Layer 2: normal signal logic
if signal == "red":
return "Stop"
elif signal == "yellow":
return "Slow Down"
elif signal == "green":
# pedestrians cross, everyone else goes
if vehicle_type == "pedestrian":
return "Cross"
else:
return "Go"
else:
return "Invalid Signal"
def traffic_signal(vehicle_type: str, signal: str, emergency: bool) -> str:
if emergency and vehicle_type == "ambulance":
return "Proceed Carefully"
actions = {"red": "Stop", "yellow": "Slow Down"}
if signal in actions:
return actions[signal]
if signal == "green":
return "Cross" if vehicle_type == "pedestrian" else "Go"
return "Invalid Signal"
Key takeaways¶
Priority ordering in conditionals
When one condition overrides all others, check it first. The emergency ambulance check must come before the signal branches, or it silently breaks for non-red signals.
Nested conditions vs. early returns
Using return early flattens deeply nested if/elif/else trees. Each branch exits immediately, so later branches don't need an else.
Dict lookup for simple mappings
{"red": "Stop", "yellow": "Slow Down"} replaces two if/elif branches. Reserve explicit if for cases that need extra logic, like the "green" branch here.