Mastering Python Type Hinting
This challenge will guide you through the process of adding type hints to Python functions and variables. Type hints improve code readability, help catch potential errors before runtime using static analysis tools, and make your code more maintainable, especially in larger projects.
Problem Description
Your task is to enhance an existing Python script by adding comprehensive type hints. You will be given a Python file containing several functions and variables that currently lack type annotations. You need to:
- Annotate Function Parameters: Add type hints to all parameters of the provided functions, specifying their expected data types.
- Annotate Function Return Values: Add type hints to indicate the expected return type of each function.
- Annotate Variables: Add type hints to important variables within the script to clarify their intended types.
- Handle Collections and Complex Types: Utilize Python's
typingmodule to correctly hint collections (like lists, dictionaries, tuples) and potentially more complex types if encountered.
The goal is to make the script fully type-annotated, allowing static analysis tools (like MyPy) to effectively check for type consistency.
Examples
Example 1: Simple Function
Input Code:
def greet(name):
return f"Hello, {name}!"
def add_numbers(a, b):
return a + b
Output Code (with type hints):
from typing import Union
def greet(name: str) -> str:
return f"Hello, {name}!"
def add_numbers(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
return a + b
Explanation:
greetfunction'snameparameter is hinted asstr, and its return value is alsostr.add_numbersfunction's parametersaandbare hinted to accept eitherintorfloat, and its return value is also hinted to beintorfloat.Unionis used to represent multiple possible types.
Example 2: Function with Collections
Input Code:
def calculate_average(numbers):
if not numbers:
return 0.0
return sum(numbers) / len(numbers)
def get_user_info(user_data):
name = user_data.get("name", "Unknown")
age = user_data.get("age", None)
return name, age
Output Code (with type hints):
from typing import List, Dict, Optional, Tuple, Any
def calculate_average(numbers: List[float]) -> float:
if not numbers:
return 0.0
return sum(numbers) / len(numbers)
def get_user_info(user_data: Dict[str, Any]) -> Tuple[str, Optional[int]]:
name = user_data.get("name", "Unknown")
age = user_data.get("age", None)
return name, age
Explanation:
calculate_average'snumbersparameter is hinted as aListoffloats, and it returns afloat.get_user_info'suser_dataparameter is hinted as aDictwithstrkeys andAnytype values. The function returns aTuplecontaining astr(name) and anOptional[int](age, meaning it can be anintorNone).
Constraints
- The provided Python script will contain at least 5 functions and several variables.
- All function parameters and return values must be type-hinted.
- All significant variables intended to hold specific data types must be type-hinted.
- You should use type hints from Python's built-in types and the
typingmodule (e.g.,List,Dict,Tuple,Optional,Union,Any). - Aim for the most specific type hints possible without making assumptions beyond what's implied by the code's logic.
- You are not required to implement new logic, only to add type hints to existing code.
Notes
- Pay close attention to the expected types of data being passed into and returned from functions.
- Consider cases where a variable or parameter might hold multiple possible types (use
Union). - If a value can be of a certain type or
None, useOptional. - For dictionaries where keys are of one type and values can be of any type,
Dict[KeyType, Any]is appropriate. - A good starting point is to run a static type checker like MyPy on your code after adding type hints to identify any missing or incorrect annotations.
- The goal is to achieve a state where a static type checker would report no errors for the given code.