Skip to content

S1Q2 · Train Ticket Booking Status

⚡ Quick Reference

Function: train_ticket(passenger: dict, available_seats: int) -> str

Core idea: Four rules applied in strict priority order -- each is an early return.

def train_ticket(passenger, available_seats):
    if not passenger["has_id"]:    return "ID Required"
    if available_seats <= 0:       return "Waiting List"
    if passenger["age"] >= 60:     return "Priority Booking"
    return "Ticket Confirmed"

Key rules (in order): - No ID → "ID Required" (checked first, overrides everything) - No seats → "Waiting List" - Age >= 60 → "Priority Booking" - Otherwise → "Ticket Confirmed"


Problem Statement

Problem

Write a function train_ticket(passenger, available_seats) where passenger is a dict with keys "age" and "has_id". Apply the four booking rules in the given order and return the appropriate status string.

Examples:

Call
train_ticket({"age": 65, "has_id": True}, 5)
Output
'Priority Booking'
Call
train_ticket({"age": 30, "has_id": False}, 5)
Output
'ID Required'
Call
train_ticket({"age": 22, "has_id": True}, 0)
Output
'Waiting List'

Understanding the problem

The rules form a strict priority chain -- each condition is only checked if all previous ones passed:

has_id?  ──No──▶  "ID Required"
   │
  Yes
   │
seats > 0?  ──No──▶  "Waiting List"
   │
  Yes
   │
age >= 60?  ──Yes──▶  "Priority Booking"
   │
   No
   │
"Ticket Confirmed"

Rule ordering determines the result for edge cases

A senior citizen without an ID still gets "ID Required" (not "Priority Booking") because the ID check comes first. A senior citizen with an ID but no seats gets "Waiting List". The order in the problem statement is the exact order the checks must be coded.

Tracing the three given examples:

Age has_id Seats ID check Seats check Age check Result
65 True 5 pass pass 65 >= 60 ✅ "Priority Booking"
30 False 5 fails ❌ -- -- "ID Required"
22 True 0 pass 0 <= 0 ❌ -- "Waiting List"

Solution approaches

def train_ticket(passenger: dict, available_seats: int) -> str:
    # Rule 1: ID is mandatory -- checked before anything else
    if not passenger["has_id"]:
        return "ID Required"

    # Rule 2: No point booking if no seats exist
    if available_seats <= 0:
        return "Waiting List"

    # Rule 3: Senior citizens get priority when seats are available
    if passenger["age"] >= 60:
        return "Priority Booking"

    # Rule 4: All other valid passengers
    return "Ticket Confirmed"
def train_ticket(passenger: dict, available_seats: int) -> str:
    checks = [
        (not passenger["has_id"],      "ID Required"),
        (available_seats <= 0,         "Waiting List"),
        (passenger["age"] >= 60,       "Priority Booking"),
    ]
    for condition, status in checks:
        if condition:
            return status
    return "Ticket Confirmed"
def train_ticket(passenger: dict, available_seats: int) -> str:
    rules = [
        (lambda p, s: not p["has_id"],    "ID Required"),
        (lambda p, s: s <= 0,             "Waiting List"),
        (lambda p, s: p["age"] >= 60,     "Priority Booking"),
    ]
    for condition, status in rules:
        if condition(passenger, available_seats):
            return status
    return "Ticket Confirmed"

Key takeaways

01

Early returns enforce priority

Returning immediately when a condition is met means later checks never run. This is cleaner than nested if/else and maps directly to the "apply rules in order" problem statement.

02

Accessing dict values with dict["key"]

passenger["has_id"] and passenger["age"] pull values from the dict by key. Since the problem guarantees both keys exist, direct access is safe and more readable than .get() with a default.

03

List of (condition, result) pairs for rule tables

The Pythonic approach stores each rule as a (condition, status) tuple in a list, then iterates until one matches. This pattern scales cleanly when the number of rules grows -- adding a new rule is just one more line in the list.