lk-geimfari / mimesis

Mimesis is a robust data generator for Python that can produce a wide range of fake data in multiple languages.
https://mimesis.name
MIT License
4.39k stars 330 forks source link

Allow a list of options as an argument to provider methods #438

Closed vitasiku closed 6 years ago

vitasiku commented 6 years ago

It would be nice, if the module allowed one to pass an optional list of possible values from which the random value is generated. This would eliminate the need to create custom provides, enums etc. E.g using Text,

from mimesis import Generic

generic = Generic('en')
generic.text.answer(options=['Yes', 'No'])

In this case, the random value generated will only come from ['Yes', 'No'] excluding 'Maybe'

In the above example, this will require modifications to https://github.com/lk-geimfari/mimesis/blob/master/mimesis/providers/text.py like so

...
class Text(BaseDataProvider):
    ...
    def answer(self, options=None) -> str:
        """Get a random answer in current language.
        Return a random value from options if set else return from the default dataset.
        :return: An answer.
        :Example:
            No
        """
        if options: 
             return self.random.choice(options)
        answers = self._data['answers']
        return self.random.choice(answers)
lk-geimfari commented 6 years ago

@vitasiku Maybe it's better to add argument exclude=['Maybe', 'Something else']?

vitasiku commented 6 years ago

@lk-geimfari thanks for the reply. My intent for this was to randomly select one value from a preset list of options. However, the options maybe named differently from those specified in the "self.data"

The exclude approach would imply that one has to be aware of what the possible values are since the choice is made from the preset values: self._data['answers'] in the memesis module.

A typical use-case: Randomly select a value from a limited set where the values are different from the preset values. More like one random value from an enum list. Eg

from mimesis import Generic
generic = Generic('en')
account = Account(
                code=generic.code.pin(),
                gender=generic.text.answer(options=['F', 'M']),
                age=generic.person.age(minimum=18, maximum=60),
                status=generic.text.answer(options=['active', 'inactive']),
                total_amount=generic.numbers.between(minimum=500, maximum=100000000),
                weekly_amount=generic.numbers.between(minimum=500, maximum=1000000),
                trans_freq=generic.numbers.between(minimum=1, maximum=100),
                lend=generic.text.answer(options=['Yes', 'No']))

I hope I have made the use case clear.

lk-geimfari commented 6 years ago

@vitasiku In such cases, you should use standard random.choice(). There no need to implement it in core, because you can do it manually, just replace generic.text.answer(options=['Yes', 'No']) to random.choice([...]). I think that this way is much shorter and clearer.

vitasiku commented 6 years ago

@lk-geimfari thanks very much. That's what I was looking for. It's not easily found in the documentation.

Could you include a whole sample code of how one calls it. What provider is it a part of?

Perhaps, an example like above can be included in the documentation to make it easier to find.

vitasiku commented 6 years ago

For future users, here is how to go about with it.

from mimesis.helpers import get_random_item

generic = Generic('en')
account = Account(
                code=generic.code.pin(),
                gender=get_random_item(['Female', 'Male']),
                status=get_random_item(['Active', 'Inactive']))