Layer System with Undo/Redo and Batch Operations
Frequency: Reported
python
"""
Layer System with Undo/Redo
Implement a class to manage a system of layers, where:
- Each layer has an ID (integer like 1, 2, 3)
- Each layer contains properties stored as key-value pairs
- Example of a layer: Layer(1, {"color": "green", "shape": "circle"})
Part 1: Basic Operations
Implement a class with the following operations:
- __init__(): Initialize the system
- apply(layer): Apply a layer with its properties to the system
- undo(): Undo the last operation
- get_state(): Return the current state of all layers
Example Flow:
system = LayerSystem()
# Operation 1
system.apply(Layer(1, {"color": "green"}))
# Operation 2
system.apply(Layer(2, {"shape": "triangle", "color": "blue"}))
# Operation 3
system.apply(Layer(1, {"color": "pink"}))
# After these operations, system state is:
# Layer 1: {"color": "pink"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
# After one undo(), system state becomes:
# Layer 1: {"color": "green"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
# After another undo(), system state becomes:
# Layer 1: {"color": "green"}
Part 2: Batch Operations
Add support for batch operations:
- begin_batch(): Start a batch of operations
- commit_batch(): Commit all operations in the batch as a single unit
- Undo should work at the batch level (one undo reverts entire batch)
Example Flow with Batches:
system = LayerSystem()
# Batch 1
system.begin_batch()
system.apply(Layer(1, {"color": "green"}))
system.apply(Layer(2, {"shape": "triangle", "color": "blue"}))
system.apply(Layer(1, {"color": "pink"}))
system.commit_batch()
# Batch 2
system.begin_batch()
system.apply(Layer(1, {"color": "blue"}))
system.apply(Layer(1, {"color": "white"}))
system.commit_batch()
# Final state after both batches:
# Layer 1: {"color": "white"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
# After one undo() (reverting Batch 2):
# Layer 1: {"color": "pink"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
# After another undo() (reverting Batch 1):
# Layer 1: {} (doesn't exist)
# Layer 2: {} (doesn't exist)
Part 3: Redo Functionality
Add redo capability:
- redo(): Restore the last undone operation or batch
Example:
system = LayerSystem()
system.apply(Layer(1, {"color": "red"}))
system.apply(Layer(1, {"color": "blue"}))
system.undo()
# State: Layer 1 = {"color": "red"}
system.redo()
# State: Layer 1 = {"color": "blue"}
system.apply(Layer(1, {"color": "green"}))
# New operation clears redo history
system.redo()
# Nothing happens (redo history was cleared)
Test Cases to Handle:
1. Undo on empty history (should do nothing)
2. Redo on empty redo stack (should do nothing)
3. New operation after undo (clears redo stack)
4. Batch with no operations (should not add to history)
5. Multiple properties on same layer
6. Updating existing layer properties
"""
class Layer:
def __init__(self, layer_id, properties):
self.id = layer_id
self.properties = properties
"""
- __init__(): Initialize the system
- apply(layer): Apply a layer with its properties to the system
- undo(): Undo the last operation
- get_state(): Return the current state of all layers
"""
class LayerSystem:
def __init__(self):
pass
def apply(self, layer): # set redo to empty
pass
def begin_batch(self):
pass
def commit_batch(self): #check if we're in batch, then add batch to history and reset batch and set inBatch to False
pass
def undo(self): # and undid to redo
pass
def redo(self):
pass
def get_state(self):
pass
system = LayerSystem()
system.apply(Layer(1, {"color": "green"}))
system.apply(Layer(2, {"shape": "triangle", "color": "blue"}))
system.apply(Layer(1, {"color": "pink"}))
print(system.get_state())
# After these operations, system state is:
# Layer 1: {"color": "pink"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
print(system.get_state())
# After one undo(), system state becomes:
# Layer 1: {"color": "green"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
print(system.get_state())
# After another undo(), system state becomes:
# Layer 1: {"color": "green"}
#test edge case for updating same layer in batch
system = LayerSystem()
# Batch 1
print("====ex 2====")
system.begin_batch()
system.apply(Layer(1, {"color": "green"}))
system.apply(Layer(2, {"shape": "triangle", "color": "blue"}))
system.apply(Layer(1, {"color": "pink"}))
system.commit_batch()
# Batch 2
system.begin_batch()
system.apply(Layer(1, {"color": "blue"}))
system.apply(Layer(1, {"color": "white"}))
system.commit_batch()
print(system.get_state())
# Final state after both batches:
# Layer 1: {"color": "white"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
print(system.get_state())
# After one undo() (reverting Batch 2):
# Layer 1: {"color": "pink"}
# Layer 2: {"shape": "triangle", "color": "blue"}
system.undo()
print(system.get_state())
# After another undo() (reverting Batch 1):
# Layer 1: {} (doesn't exist)
# Layer 2: {} (doesn't exist)Source: community report, Aug 2026