Generic Data Structures with Type Hints
Python's type hinting system allows us to create generic types, enabling us to write more robust and reusable code. This challenge focuses on implementing a simple generic stack data structure using Python's TypeVar and type hints. Understanding generics is crucial for writing type-safe code that can work with various data types without sacrificing clarity or runtime errors.
Problem Description
You are tasked with creating a generic Stack class that can hold elements of any type. The Stack class should support the following operations:
push(item): Adds an item to the top of the stack.pop(): Removes and returns the item at the top of the stack. Raises anIndexErrorif the stack is empty.peek(): Returns the item at the top of the stack without removing it. Raises anIndexErrorif the stack is empty.is_empty(): ReturnsTrueif the stack is empty,Falseotherwise.size(): Returns the number of elements in the stack.
The class should be generic, meaning it can be instantiated with any type, and the type of the elements stored in the stack should be consistent with the type specified during instantiation. Use TypeVar to define the generic type.
Key Requirements:
- Use
TypeVarto define a generic typeT. - Implement the
push,pop,peek,is_empty, andsizemethods. - Raise an
IndexErrorwhenpoporpeekis called on an empty stack. - Ensure type safety: the stack should only hold elements of the specified type.
Examples
Example 1:
Input:
stack = Stack[int]()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop())
print(stack.peek())
print(stack.is_empty())
print(stack.size())
Output:
3
3
False
2
Explanation: A stack of integers is created. Three integers are pushed onto the stack. The top element (3) is popped, then the top element (3) is peeked without being removed. The stack is not empty, and it contains 2 elements.
Example 2:
Input:
stack = Stack[str]()
stack.push("hello")
stack.push("world")
print(stack.pop())
print(stack.is_empty())
Output:
world
False
Explanation: A stack of strings is created. Two strings are pushed onto the stack. The top element ("world") is popped. The stack is not empty.
Example 3: (Edge Case)
Input:
stack = Stack[float]()
print(stack.pop())
Output:
IndexError: pop from empty stack
Explanation: An empty stack of floats is created. Attempting to pop from an empty stack raises an IndexError.
Constraints
- The stack should be implemented using a Python list internally.
- The
pushoperation should have a time complexity of O(1). - The
popandpeekoperations should have a time complexity of O(1). - The
is_emptyandsizeoperations should have a time complexity of O(1). - The stack should be able to hold a maximum of 1000 elements. (This is a practical limit, not a strict requirement for correctness, but consider it for potential future scaling).
Notes
- Remember to use type hints to specify the generic type
T. - Consider using the
__init__method to initialize the internal list. - The
IndexErrorshould be raised with a descriptive message like "pop from empty stack" or "peek from empty stack". - This problem focuses on the core concepts of generics. Error handling beyond the specified
IndexErroris not required. - Think about how to ensure type safety when pushing elements onto the stack. While Python's runtime type checking isn't strict, using type hints helps with static analysis and code clarity.