Back to Figma questions
CodingSoftware Engineer

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