tiramisu/doc/own_option.md

183 lines
5.4 KiB
Markdown

# Create it's own option
## Generic regexp option: "RegexpOption"
Use "RegexpOption" to create custom option is very simple.
You just have to create an object that inherits from "RegexpOption" and that has the following class attributes:
- \_\_slots\_\_: with new data members (the values should always be "tuple()")
- \_type = with a name
- \_display_name: with the display name (for example in error message)
- \_regexp: with a compiled regexp
Here an example to an option that only accept string with on lowercase ASCII vowel characters:
```python
import re
from tiramisu import RegexpOption
class VowelOption(RegexpOption):
__slots__ = tuple()
_type = 'vowel'
_display_name = "string with vowel"
_regexp = re.compile(r"^[aeiouy]*$")
```
Let's try our object:
```python
VowelOption('vowel', 'Vowel', 'aae')
```
```python
try:
VowelOption('vowel', 'Vowel', 'oooups')
except ValueError as err:
print(err)
```
returns:
```python
"oooups" is an invalid string with vowel for "Vowel"
```
## Create a custom option
An option always inherits from "Option" object. This object has the following class attributes:
- \_\_slots\_\_: a tuple with new data members (by default you should set "tuple()")
- \_type = with a name
- \_display_name: with the display name (for example in error message)
Here an example to an lipogram option:
```python
from tiramisu import Option
from tiramisu.error import ValueWarning
import warnings
class LipogramOption(Option):
__slots__ = tuple()
_type = 'lipogram'
_display_name = 'lipogram'
#
# First of all we want to add a custom parameter to ask the minimum length (min_len) of the value:
def __init__(self,
*args,
min_len=100,
**kwargs):
# store extra parameters
extra = {'_min_len': min_len}
super().__init__(*args,
extra=extra,
**kwargs)
#
# We have a first validation method.
# In this method, we verify that the value is a string and that there is no "e" on it:
# Even if user set warnings_only attribute, this method will raise.
def validate(self,
value):
# first, valid that the value is a string
if not isinstance(value, str):
raise ValueError('invalid string')
# and verify that there is any 'e' in the sentense
if 'e' in value:
raise ValueError('Perec wrote a book without any "e", you could not do it in a simple sentence?')
#
# Finally we add a method to valid the value length.
# If "warnings_only" is set to True, a warning will be emit:
def second_level_validation(self,
value,
warnings_only):
# retrive parameter in extra
min_len = self.impl_get_extra('_min_len')
# verify the sentense length
if len(value) < min_len:
# raise message, in this case, warning and error message are different
if warnings_only:
msg = f'it would be better to have at least {min_len} characters in the sentence'
else:
msg = f'you must have at least {min_len} characters in the sentence'
raise ValueError(msg)
```
Let's test it:
1. the character "e" is in the value:
```python
try:
LipogramOption('lipo',
'Lipogram',
'I just want to add a quality string that has no bad characters')
except ValueError as err:
print(err)
```
returns:
```
"I just want to add a quality string that has no bad characters" is an invalid lipogram for "Lipogram", Perec wrote a book without any "e", you could not do it in a simple sentence?
```
2. the character "e" is in the value and warnings_only is set to True:
```python
try:
LipogramOption('lipo',
'Lipogram',
'I just want to add a quality string that has no bad characters',
warnings_only=True)
except ValueError as err:
print(err)
```
```
"I just want to add a quality string that has no bad characters" is an invalid lipogram for "Lipogram", Perec wrote a book without any "e", you could not do it in a simple sentence?
```
3. the value is too short
```python
try:
LipogramOption('lipo',
'Lipogram',
'I just want to add a quality string that has no bad symbols')
except ValueError as err:
print(err)
```
returns:
```
"I just want to add a quality string that has no bad symbols" is an invalid lipogram for "Lipogram", you must have at least 100 characters in the sentence
```
4. the value is too short and warnings_only is set to True:
```python
warnings.simplefilter('always', ValueWarning)
with warnings.catch_warnings(record=True) as warn:
LipogramOption('lipo',
'Lipogram',
'I just want to add a quality string that has no bad symbols',
warnings_only=True)
if warn:
print(warn[0].message)
```
returns:
```
attention, "I just want to add a quality string that has no bad symbols" could be an invalid lipogram for "Lipogram", it would be better to have at least 100 characters in the sentence
```
5. set minimum length to 50 characters, the value is valid:
```python
LipogramOption('lipo',
'Lipogram',
'I just want to add a quality string that has no bad symbols',
min_len=50)
```