Hone logo
Hone
Problems

Robust Data Validation in Python

Data validation is a crucial aspect of any application that handles user input or external data sources. This challenge asks you to implement a flexible data validation system in Python, allowing you to define rules for various data types and ensure data integrity. Successfully completing this challenge will demonstrate your understanding of data types, functions, and error handling in Python.

Problem Description

You are tasked with creating a DataValidator class that can validate data against a set of predefined rules. The validator should support validation for integers, floats, and strings. For each data type, you'll define specific validation rules (e.g., range checks for integers, minimum/maximum values for floats, allowed values for strings). The class should provide a validate method that takes data and a dictionary of validation rules as input and returns a boolean indicating whether the data is valid according to the rules. If the data is invalid, the validate method should raise a ValueError with a descriptive message explaining the reason for the failure.

Key Requirements:

  • Data Type Support: The validator must handle integers, floats, and strings.
  • Rule Definitions: Rules should be defined as a dictionary, specifying the type of data and the validation criteria.
  • Error Handling: Invalid data should raise a ValueError with a clear error message.
  • Flexibility: The system should be easily extensible to support additional data types and validation rules in the future.

Expected Behavior:

The validate method should return True if the data is valid according to the provided rules. If the data is invalid, it should raise a ValueError with a message indicating the specific rule that was violated. The error message should be informative enough to help the user understand what went wrong.

Edge Cases to Consider:

  • Empty rule dictionaries.
  • Data types not supported by the validator.
  • Invalid rule formats within the dictionary (e.g., missing keys, incorrect data types for rule values).
  • Data that is of the correct type but fails the validation criteria (e.g., an integer outside the allowed range).
  • Handling of None values. Consider whether None should be considered valid or invalid, and how to handle it in the rules.

Examples

Example 1:

Input: data = 10, rules = {"type": "integer", "min": 0, "max": 20}
Output: True
Explanation: The integer 10 is within the range of 0 to 20.

Example 2:

Input: data = -5, rules = {"type": "integer", "min": 0, "max": 20}
Output: ValueError: Integer value -5 is below the minimum allowed value of 0.
Explanation: The integer -5 is less than the minimum allowed value of 0.

Example 3:

Input: data = "apple", rules = {"type": "string", "allowed_values": ["apple", "banana", "orange"]}
Output: True
Explanation: The string "apple" is one of the allowed values.

Example 4:

Input: data = "grape", rules = {"type": "string", "allowed_values": ["apple", "banana", "orange"]}
Output: ValueError: String value 'grape' is not in the list of allowed values.
Explanation: The string "grape" is not in the list of allowed values.

Example 5:

Input: data = None, rules = {"type": "integer", "min": 0, "max": 20}
Output: ValueError: Data is None, but integer validation requires a value.
Explanation:  None is not a valid integer.

Constraints

  • The rules dictionary will always be passed as a dictionary.
  • The data can be of type int, float, str, or None.
  • The validator should be able to handle at least 100 validation requests per second. (This is a general performance expectation, not a strict requirement to be tested).
  • The code should be well-documented and easy to understand.

Notes

  • Consider using helper functions to encapsulate the validation logic for each data type.
  • Think about how to make the validator extensible to support new data types and validation rules without modifying the core class.
  • Pay close attention to error messages – they should be clear, concise, and informative.
  • The allowed_values rule for strings should be treated as a case-sensitive comparison.
  • You can assume that the type key in the rules dictionary will always be one of "integer", "float", or "string". No need to handle invalid type values.
Loading editor...
python