Hone logo
Hone
Problems

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 an IndexError if the stack is empty.
  • peek(): Returns the item at the top of the stack without removing it. Raises an IndexError if the stack is empty.
  • is_empty(): Returns True if the stack is empty, False otherwise.
  • 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 TypeVar to define a generic type T.
  • Implement the push, pop, peek, is_empty, and size methods.
  • Raise an IndexError when pop or peek is 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 push operation should have a time complexity of O(1).
  • The pop and peek operations should have a time complexity of O(1).
  • The is_empty and size operations 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 IndexError should 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 IndexError is 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.
Loading editor...
python