Skip to main content

UserResponseCollector facilitates the collection of user responses from the command line.

Project description

UserResponseCollector

Source code: GitHub

UserResponseCollector is a Python library that facilitates the collection of user responses from the command line (Console). It supports text string input, selection from a list of options, integer input, floating point input, and input of file paths for opening or saving files.

It is extensible, allowing developers to create custom input types as needed. It can also be extended to obtain input from other sources, such as a graphical user interface.

The Command design pattern is followed:

  • The Receiver participant interface is defined, and the Console implementation is provided.
  • The Command participant interface is defined, and multiple ConcreteCommand implementations (e.g., for selecting from a list of options or entering an integer) are provided.

Extensibility is achieved by creating new ConcreteCommand classes that implement the Command interface, if a new type of input is needed. UserQueryCommand child classes (e.g. UserQueryCommandNumberInteger) must implement:

  • _doCreatePromptText() - Generates string of text used to prompt user for input

  • _doProcessRawResponse(...) - Converts the raw response text string of user input to an object of required type

  • _doValidateProcessedResponse(...) - Tests that the object of required type meets any other requirements, such as that an entered integer is greater than or equal to a minimum value

  • UserQueryCommand child classes can also optionally extend:

  • _doGetExtraDict() - Returns dictionary of key/value pairs to pass to UserQueryReceiver.GetRawResponse(...) method. The base implemetation adds the "query_type" key, with the value of the type of this UserQueryCommand. Note: Clients must assume that the Receiver implementation may not use any or all of the key/value pairs provided.

If a new source of input is needed, a new Receiver subclass can be created that implements the Receiver interface.

Credit where credit is due

  • Command and Template Method (followed by UserQueryCommand.Execute()) design patterns follow the concepts, UML diagrams, and examples provided in "Design Patterns: Elements of Reusable Object-Oriented Software," by Eric Gamma, Richard Helm, Ralph Johnson, and John Vlissides, published by Addison-Wesley, 1995.
  • UserQueryReceiver_GetCommandReceiver is a global prebound method that returns the global, single instance of a concrete UserQueryReceiver. The Global Object design pattern and Prebound Method design pattern described by Brandon Rhodes are followed. See for reference: (1) Global Object Pattern: https://python-patterns.guide/python/module-globals/, (2) Prebound Method Pattern: https://python-patterns.guide/python/prebound-methods/

Basic usage

The simplest way to use the library is through the functions it provides for each input type. Note that all the usage examples below assume that the UserResponeCollector package has been installed from PyPI, and is available for import. If this is not the case, and you are just working with the source code, adjust the import statements by dropping the leading 'UserResponseCollector.' from the module paths.

Integer input

from UserResponseCollector.UserQueryCommand import askForInt
number = askForInt(query_preface='How many widgets will you purchase?', minimum=1, maximum=100)

The user will be prompted to enter an integer between 1 and 100, with the question, "How many widgets will you purchase?". If the user enters text that cannot be converted to an integer, or an integer outside the specified range, they will be prompted to try again. For example:

How many widgets will you purchase?
Enter and integer number between 1 and 100: 150

'150' is greater than 100. Please try again.
How many widgets will you purchase?
Enter and integer number between 1 and 100: 90

The minimum and maximum arguments to the function can be set to None (which are the defaults) if limits are not required.

Floating point input

from UserResponseCollector.UserQueryCommand import askForFloat
price = askForFloat(query_preface='What is the price of the widget in dollars?', minimum=0.25, maximum=100)

The user will be prompted to enter a floating point number between 0.25 and 100, with the question, "What is the price of the widget in dollars?". If the user enters text that cannot be converted to a float, or a float outside the specified range, they will be prompted to try again. For example:

What is the price of the widget in dollars?
Enter a floating point number between 0.25 and 100: 0

'0' is less than 0.25. Please try again.
What is the price of the widget in dollars?
Enter a floating point number between 0.25 and 100: 50.75

The minimum and maximum arguments to the function can be set to None (which are the defaults) if limits are not required.

Text string input

from UserResponseCollector.UserQueryCommand import askForStr
name = askForStr(query_preface='What is your name?', max_length=15)

The user will be prompted to enter a text string with the question, "What is your name?". If the user enters a string that is shorter than 1 character or longer than 25 characters, they will be prompted to try again. For example:

What is your name?
Enter a string of text no longer than 15 characters.George Washington

'George Washington' is longer than 15 characters. Please try again.
What is your name?
Enter a string of text no longer than 15 characters.G. Washington

The default maximum length is 25 characters. The argument can be set to None if there is no character limit.

Menu selection input

from UserResponseCollector.UserQueryCommand import askForMenuSelection
name = askForMenuSelection(query_preface='What option do you want?', query_dic={'a':'Option A', 'b':'Option B'})

The user will be prompted to enter text corresponding to one of the keys in the query_dic argument. If the user enters a string that does not match one of the keys, they will be prompted to try again. For example:

What option do you want?
Choose (a)Option A, (b)Option B: 2

'2' is not a valid response. Please try again.
What option do you want?
Choose (a)Option A, (b)Option B: a

Path for saving file input

from UserResponseCollector.UserQueryCommand import askForPathSave
name = askForPathSave(query_preface='Where do you wish to save the data?')

The user will be prompted to enter a file path with the question, "Where do you wish to save the data?". If the user enters an invalid file path, they will be asked to try again. If the file path already exists, the user will be asked to confirm that they wish to overwrite it. For example:

Where do you wish to save the data?
Enter a valid file system path, without file extension, and with escaped backslashes.C:\\temp\\junk.txt

'C:\\temp\\junk.txt' is an existing file. Do you want to overwrite it?
Choose (y)Yes, (n)No:

Current limiations/issues:

  • The direction to not include a file extension is provided under the assumption that the file path is intended for saving a pickle file.
  • The testing in the code for the validity of the file path is not reliable.

Path for opening file input

from UserResponseCollector.UserQueryCommand import askForPathOpen
name = askForPathOpen(query_preface='Which data file do you wish to open?')

The user will be prompted to enter a file path with the question, "Which data file do you wish to open?". If the user enters an invalid file path, they will be asked to try again. For example:

Which data file do you wish to open?
Enter a valid file system path, without file extension, and with escaped backslashes.C:\\temp\\junk.txt

'C:\\temp\\junk.txt' is not a valid file path. Please try again.

Current limiations/issues:

  • The direction to not include a file extension is provided under the assumption that the file path is intended for opening a pickle file.
  • The testing in the code for the validity of the file path is not reliable.

Advanced Usage

It is also possible to use the Receiver and Command objects directly to obtain input, rather than using the functions that wrap these objects. Note that the usage example below assumes that the UserResponeCollector package has been installed from PyPI, and is available for import. If this is not the case, and you are just working with the source code, adjust the import statements by dropping the leading 'UserResponseCollector.' from the module paths. Make the same adjustment in the receiver = ... line below.

Integer input

from UserResponseCollector.UserQueryCommand input UserQueryCommandNumberInteger
import UserResponseCollector.UserQueryReceiver
# Build a query for the user to obtain an integer
receiver = UserResponseCollector.UserQueryReceiver.UserQueryReceiver_GetCommandReceiver()
query_preface = 'How many widgets will you purchase?'
command = UserQueryCommandNumberInteger(receiver, query_preface, minimum = 1, maximum = 100)    
# Initiate the input request
response = command.Execute()
# Print the response
print(f"You entered the integer {response}.")

Unittests

Unittests for the UserQueryReceiver are in the tests directory, with filenames starting with test_. To run the unittests, type python -m unittest discover -s ..\..\tests -v in a terminal window in the src\UserResponseCollector directory.

License

MIT License. See the LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

userresponsecollector-1.1.0.tar.gz (58.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

userresponsecollector-1.1.0-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file userresponsecollector-1.1.0.tar.gz.

File metadata

  • Download URL: userresponsecollector-1.1.0.tar.gz
  • Upload date:
  • Size: 58.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for userresponsecollector-1.1.0.tar.gz
Algorithm Hash digest
SHA256 5bd866b94e024ba6f2905f21106c6bffaec1a63dea57bbf0a9e9e414aee2f215
MD5 722a4cd04836a45889f25ae5181ec350
BLAKE2b-256 86122bbf511476f1696840e4e2c3c874b5cedb4b2c83a537a1e8ddfbc66d38f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for userresponsecollector-1.1.0.tar.gz:

Publisher: release.yml on KevinRGeurts/UserResponseCollector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file userresponsecollector-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for userresponsecollector-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5bdbd76aaf905ea91fdf9be59942e9617caa0cbfc6a6bee5d25fdd00560102c1
MD5 698640858630cec47e2f993a4d740f4a
BLAKE2b-256 700da1e76e5065d00664aeb573dcbf572e25c916a663cf4eadb6ad009c0ff964

See more details on using hashes here.

Provenance

The following attestation bundles were made for userresponsecollector-1.1.0-py3-none-any.whl:

Publisher: release.yml on KevinRGeurts/UserResponseCollector

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page