puissant package

Module contents

puissant provides a collection of functions for command-line validated user input. The following conveninence user-input functions are available:

All of the above functions are wrappers around puissant.vinput(), which allows writing generic user-validated input functions.

Examples

  • yes or no questions (bool output):

    >>> from puissant import *
    >>> yes_no(prompt = 'Do you want to continue', default = 'n')
    Do you want to continue [y/n]?(default:n) y
    True
    >>> yes_no(prompt = 'Do you want to continue', default = 'n')
    Do you want to continue [y/n]?(default:n) <= Enter
    False
    
  • semantic versioning input:

    >>> semantic_version('Enter next version: ')
    Enter next version: a1.3.2
    Not conformat to Semantic Versioning 2.0.0-rc.2 spec.
    Enter next version: 1.3.2-alpha+001
    (1, 3, 2, 'alpha', '001')
    >>>
    
  • menu input:

    >>> menu(prompt = 'what next?', options = ['restart', 'continue', 'quit'])
    what next?
     1 - restart
     2 - continue
     3 - quit
    select an item [range: 1..3]: 5
    input must be in range 1..3.
    select an item [range: 1..3]: 3
    (2, 'quit')
    
  • tickbox menu:

    >>> tickbox_menu('add extras', ['mayo', 'ketchup', 'garlic', 'tabasco'])
    add extras
    1  [ ] - mayo
    2  [ ] - ketchup
    3  [ ] - garlic
    4  [ ] - tabasco
    
    - type a number to tick the option.
    - "a" selects all.
    - "n" de-selects all.
    - "d" selection done.
    
    Option? : 1
    add extras
    1  [x] - mayo
    2  [ ] - ketchup
    3  [ ] - garlic
    4  [ ] - tabasco
    
    - type a number to tick the option.
    - "a" selects all.
    - "n" de-selects all.
    - "d" selection done.
    
    Option? : 4
    add extras
    1  [x] - mayo
    2  [ ] - ketchup
    3  [ ] - garlic
    4  [x] - tabasco
    
    - type a number to tick the option.
    - "a" selects all.
    - "n" de-selects all.
    - "d" selection done.
    
    Option? : d
    [(0, 'mayo'), (3, 'tabasco')]
    
  • string enumeration input:

    >>> enum_str(prompt = 'how do you want it?', enum = ['fried', 'poached', 'scrambled'])
    how do you want it? (valid choices: fried, poached, scrambled):
    raw
     input must be one of fried, poached, scrambled.
    how do you want it? (valid choices: fried, poached, scrambled):
    poached
    'poached'
    
  • ranged integer input:

    >>> ranged_int(prompt = 'how old are you?', low = 1, high = 150)
    how old are you? [range: 1..150]: -3
    input must be in range 1..150.
    how old are you? [range: 1..150]: 151
    input must be in range 1..150.
    how old are you? [range: 1..150]: 35
    35
    
puissant.menu(prompt, options, retries=-1)[source]

gets a validated input string from a string menu.

Example:

>>> from puissant import *
>>> menu(prompt = 'pick a fruit', options = ['pear','apple','orange'])
pick a fruit
 1 - pear
 2 - apple
 3 - orange
select an item [range: 1..3]: 4
input must be in range 1..3.
select an item [range: 1..3]: pear
input must be of type int.
select an item [range: 1..3]: 2
(1, 'apple')
Parameters:
  • prompt (str) – user input prompt.

  • options (List[str]) – list of strings from which users selects one.

  • retries – numbers of retries before input is aborted (-1 = no limit)

Returns:

the string selected by user from options, if input is valid.

Raises:

ValueError – if invalid input is entered for retries + 1

Return type:

str

puissant.yes_no(prompt, default=None, retries=-1)[source]

gets validated input from user for a yes/no question.

Example:

>>> from puissant import *
>>> yes_no('do you want desert')
do you want desert [y/n]?maybe
 input must be one of y, n, yes, no.
do you want desert [y/n]?y
True
>>> yes_no('are you ok', default = 'n')
are you ok [y/n]?(default:n)
False
Parameters:
  • prompt (str) – user input prompt.

  • default (str | None) – default input value if user enters newline only.

  • retries (int) – allowed number of extra attempts for user input (-1 = unlimited)

Returns:

True (affirmative answer) or False (negative answer)

Raises:

ValueError – if invalid input is entered for retries + 1

Return type:

bool

puissant.tickbox_menu(prompt, options)[source]

gets validated, multiple user input from a tick-box menu.

Examples:

>>> tickbox_menu('make up your own menu', options = ['fries', 'burger', 'onion rings', 'salad'])
make up your own menu
1  [ ] - fries
2  [ ] - burger
3  [ ] - onion rings
4  [ ] - salad

- type a number to tick the option.
- "a" selects all.
- "n" de-selects all.
- "d" selection done.

Option? : 1
make up your own menu
1  [x] - fries
2  [ ] - burger
3  [ ] - onion rings
4  [ ] - salad

- type a number to tick the option.
- "a" selects all.
- "n" de-selects all.
- "d" selection done.

Option? : 2
make up your own menu
1  [x] - fries
2  [x] - burger
3  [ ] - onion rings
4  [ ] - salad

- type a number to tick the option.
- "a" selects all.
- "n" de-selects all.
- "d" selection done.

Option? : d
[(0, 'fries'), (1, 'burger')]
Parameters:
  • prompt (str) – user input prompt.

  • options (List[str]) – list of options to tick.

Returns:

a list of tuples, each one containing the index of a ticket item, and the item itself.

Return type:

List[Tuple[int, str]]

puissant.enum_str(prompt, enum, default=None, quiet=False, retries=-1)[source]
Parameters:
  • prompt (str) –

  • enum (List[str]) –

  • default (str | None) –

  • quiet (bool) –

Return type:

str

puissant.ranged_int(prompt, low, high, default=None, retries=-1)[source]

gets ranged integer validated user input.

Example:

>>> ranged_int(prompt = 'roll a dice...', low = 1, high = 6)
roll a dice... [range: 1..6]: 0
input must be in range 1..6.
roll a dice... [range: 1..6]: 1
1
Parameters:
  • prompt (str) – user input prompt.

  • low (int) – minimum allowed integer input.

  • high (int) – maximum allowed integer input.

  • default (int | None) – default result if user only presses Return.

  • retries (int) – allowed number of attempts for user input.

Returns:

The integer user input, if it is deemed valid.

Raises:

ValueError – after retries + 1 invalid user input attemtpts.

Return type:

int

puissant.ranged_float(prompt, low, high, default=None, retries=-1)[source]

gets ranged float validated user input.

Example:

>>> ranged_float('how tall are you in meters?', 0.5, 2.75)
how tall are you in meters? [range: 0.5..2.75]: 0.3
input must be in range 0.5..2.75.
how tall are you in meters? [range: 0.5..2.75]: 3.0
input must be in range 0.5..2.75.
how tall are you in meters? [range: 0.5..2.75]: 1.75
1.75
Parameters:
  • prompt (str) – user input prompt.

  • low (float) – minimum allowed floating point input.

  • high (float) – maximum allowed floating point input.

  • default (float | None) – default result if user only presses Return.

  • retries – allowed number of extra attempts for user input.

Returns:

The floating point user input, if it is deemed valid.

Raises:

ValueError – after retries + 1 invalid user input attemtpts.

Return type:

float

puissant.semantic_version(prompt, retries=-1)[source]

gets Semantic Version 2.0.0-rc.2 validated input.

Example:

>>> semantic_version('Enter next version: ')
Enter next version: a1.3.2
Not conformat to Semantic Versioning 2.0.0-rc.2 spec.
Enter next version: 1.3.2-alpha+001
(1, 3, 2, 'alpha', '001')
>>>
Parameters:
  • prompt (str) – user input prompt

  • retries – allowed number of extra attempts for user input

Returns:

A tuple (major, minor, patch, release, build) with version data.

Raises:

ValueError – after retries + 1 invalid user input attemtpts.

Return type:

Tuple[int, int, int, str | None, str | None]

puissant.vinput(prompt, typ, default=None, retries=-1, nrange=None, enum=None, pre_fn=<function _identity>, validation_fn=<function _always_good>, post_fn=<function _identity>, type_err_msg=None, enum_err_msg=None, range_err_msg=None)[source]

performs validated command line user input.

Examples:

  • yes/no question:

    >>> from puissant import *
    >>> vinput(prompt = 'Do you want to continue [y/n]? ',
    ...        typ = str,
    ...        enum = ['y','n','yes','no'],
    ...        pre_fn = str.lower,
    ...        post_fn = lambda x: x in ['y','yes']
    ...
    ... )
    Do you want to continue [y/n]? maybe
     input must be one of y, n, yes, no.
    Do you want to continue [y/n]? 2
     input must be one of y, n, yes, no.
    Do you want to continue [y/n]? y
    True
    
  • string enumeration choice:

    >>> vinput(prompt = 'which color do you prefer? ',
    ...        typ = str,
    ...        enum = ['green','blue','red','yellow','purple'])
    which color do you prefer? white
     input must be one of green, blue, red, yellow, purple.
    which color do you prefer? 3
     input must be one of green, blue, red, yellow, purple.
    which color do you prefer? green
    'green'
    
  • ranged integer input with custom error message and retries limit:

    >>> vinput(prompt = 'enter your age: ',
    ...        typ = int,
    ...        nrange = (0,130),
    ...        retries = 2,
    ...        range_err_msg = "Surely that's not your age!")
    enter your age: 150
    Surely that's not your age!
    enter your age: james
    input must be of type int.
    enter your age: -3
    Surely that's not your age!
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/garciaal/prj/puissant/puissant/__init__.py", line 233, in vinput
        raise ValueError(f"Invalid user input for {tries - 1} times.")
    ValueError: Invalid user input for 3 times.
    
Parameters:
  • prompt (str) – prompt for the user.

  • typ (Type[T]) – expected type of user input.

  • default (T | None) – default value for user input if only Return pressed.

  • retries (int) – allowed number of user input retries. -1 for infinte.

  • nrange (Tuple[T, T] | None) – optional allowed (min,max) range for user input.

  • enum (Sequence[T] | None) – optional enumeration of allowed user inputs.

  • pre_fn (Callable[[T], Any]) – hook for a function to be called on input data prior to validate it. If not fgiven, identity function is used (returns its input unchanged)

  • validation_fn (Callable[[T], bool]) – optional custom validation function. If none given, data is always deemed valid, if it has type typ and meets belongs to nrange or enum if given.

  • post_fn (Callable[[T], Any]) – optional post-validation function to be run on input data. If not given, the identity function is used (returns its input unchanged)

  • type_err_msg (str | None) – optional custom message to print if input data is not of type type.

  • enum_err_msg (str | None) – custom message to print if input data is not included in enum.

  • range_err_msg (str | None) – custom message to print if input data is out of range nrange

Returns:

post_fn(pre_fn(user_input)) if input is deemed valid.

Raises:

ValueError – after retries + 1 invalid user input attempts.

Return type:

Any