API

The public interface for jobcalc.

Core

The following items are found in the jobcalc.core module, but are also loaded into the jobcalc namespace.

class jobcalc.BaseCalculator(costs=[], margins=[], discounts=[], deductions=[], ignore_margins=None)[source]

The BaseCalculator class know’s how to take costs, a margin, a discount (percentage discount), and deductions and calculate a total with those items.

All items can be either single or iterables of items, but all get stored as a list. And the sum of that list of items makes up the total for a given item.

Parameters:
  • costs (Iterable) – Either a single item or list of items that can be converted to a Currency, used as the subtotal for a calculation.
  • margins (Iterable) – An item or list of items that can be converted to a Percentage, used as the profit margin for the calculation.
  • discounts (Iterable) – An item or list of items that can be converted to a Percentage, used as a percentage discount for the calculation.
  • deductions (Iterable) – An item or list of items that can be converted to a Currency, used as monetary deduction for the calculation.
  • ignore_margins (Optional[bool]) – A bool determining whether to ignore margins if any of the items in costs are other Calculator instances. Defaults to False.
Return type:

None

static calculate(*args, **kwargs)[source]

Just attaches the calculate() function as a staticmethod. This is the method called in total(), so if a sub-class would like to implement a custom calculation, they can override this method.

Return type:Currency
ctx(ignore_margins=None)[source]

A context manager that yields a Context that is properly set up to be used in a calculation.

Parameters:ignore_margins (Optional[bool]) – A bool to determine whether to ignore margins in the subtotal if our costs include other Calculator instances. This will fallback to self.ignore_margins if not supplied.
Return type:Context
subtotal(ignore_margins=None)[source]

Calculate the subtotal of the costs. This is used because costs can also consist of other calculators, so we call either total() or subtotal() accordingly on those items.

Parameters:ignore_margins (Optional[bool]) – A boolean, if True, then we call subtotal on child calculators, if it’s False then we call total. We fallback to self.ignore_margins if this is not passed in.
Return type:Currency
total()[source]

Calculates the total for the current settings of the instance.

This method will convert all the items in to their appropriate type, which can cause errors if the items can not be converted properly. The most common error will be decimal.InvalidOperation.

Return type:Currency
class jobcalc.Calculator(*, formatters=[], hours=[], rate=None, config=None, **kwargs)[source]

Extends BaseCalculator. Adds the ability to attach formatters, to render a formatted output. Adds hours and a rate option. The hours will be summed and multiplied by the rate and added to the subtotal of the job. Also adds the ability to pass in a Config instance for common configuration of a Calculator.

Parameters:
  • formatters (Iterable) – A single or iterable of BaseFormatter‘s to format the output.
  • hours (Iterable) – A single or iterable of items that can be converted to a decimal.Decimal.
  • rate (Union[str, int, None]) – An single item that can be converted to a decimal.Decimal that represents an hourly rate.
  • config (Optional[Config]) – A Config instance to use for values, either set or loaded from the environment.
Return type:

None

ctx(strict=False)[source]

Return a properly configured Context to be used.

Note

This can also raise errors if hours or rate can not be converted to a decimal.Decimal. Most common error will be a decimal.InvalidOperation error.

Parameters:strict (bool) – If True an error will be raised if hours are set on an instance, but no rate has been set. Default is False
Raises:HourlyRateError – If strict is True and no hourly rate has been set.
Return type:Context
rate

Used as the hourly rate for a calculator. Defaults to ‘0’. This will not accept anything that is not greater or equal to 0 or anything that can not be converted to a decimal.Decimal.

render(seperator='nn')[source]

Return a string output of all the formatters for an instance. Joined by the seperator.

If no formatters have been set, then we fall back to :py:class`BasicFormatter`, which will just output the total() as a formatted currency string.

Parameters:seperator (str) – A string to use as the seperator. Defaults to a double new-line.
Return type:str
subtotal(**kwargs)[source]

Add’s sum of costs + (rate * hours) for the subtotal.

Parameters:kwargs – Get passed to super‘s subtotal method.
Return type:Currency
update(updates=None, append=True, **kwargs)[source]

A convenience method to update the common items of an instance.

Parameters:
  • updates (Optional[Dict]) – Optional dict used for the updates where the keys are attribute names and the values are the items to set for the attribute.
  • append (bool) – A bool, if True then we add the items to the existing attribute, if False then we remove any items already set with the new items. Default is True.
  • kwargs – Same as updates.

Example:

>>> calc = Calculator()
>>> calc.update({'margins': '50'})
>>> assert calc.margins[-1] == '50'
# True
>>> calc.update(costs='123')
>>> assert calc.costs[-1] == '123'
# True
Return type:None
class jobcalc.TerminalCalculator(*, colors=None, **kwargs)[source]

Extends Calculator for use in the command line interface.

Parameters:
  • colors (Optional[Iterable]) – A 6 tuple or ColorKey of colors
  • kwargs – Extra args to pass to :py:class:Calculator
Return type:

None

is_empty(attr)[source]

Determines if an attribute is considered empty, or equal to ‘0’.

If there are default hours set by an environment variable, then hours are considered empty if the sum of (hours - default_hours) are ‘0’.

Parameters:attr (str) – The name of the attribute to check.
Return type:bool
key_for_prompt(prompt)[source]
A helper to return the correct key (attribute name) to use for

a prompt.

This is the opposite of the normalize() method. In which it ensures the return value is pluralized for most cases as that’s the key that can be used in the update() method for an instance.

This is helpful when making multiple prompts that save their values in a dict, that later is used to update the attributes on an instance.

Parameters:prompt (str) –

The attribute the prompt is for.

Example:

>>> calc = TerminalCalculator()
>>> calc.key_for_prompt('discount')
'discounts'
>>> calc.key_for_prompt('rates') # handle accidental plural's
'rate'
Return type:str
normalize(attr)[source]

A helper to normalize an attribute name, as most context’s expect the name to not be pluralized (except hours), so we chop off the ‘s’ if applicable.

This is also helpful if using prompt_for() method, to make sure the name for the prompt is correct.

Parameters:attr (str) – The attribute name to normalize.
Return type:str
prompt_all()[source]

Prompt the user for all input’s, also showing the current value, and add the values to this instance appropriately.

Return type:None
prompt_for(prompt, **kwargs)[source]

A context manager that prompt’s a user for input, and yields a PromptResponse.

Valid prompts are ‘margin’, ‘discount’, ‘deduction’, ‘cost’, ‘hours’, and ‘rate’. We will also do/ call the right method if use the plural form of prompt (ex. ‘margins’).

Parameters:
  • prompt (str) – The attribute to prompt for (ex. ‘margin’)
  • kwargs – They get passed to the prompt_for_{prompt} command.

Example:

>>> calc = TerminalCalculator()
>>> with calc.prompt_for('margin', default='0') as result:
...    calc.update(margins=result.value)
Return type:PromptRespone
prompt_for_cost(default=None, *, type=<jobcalc.param_types.CostsType object>, is_single=False, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for cost(s) for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

prompt_for_deduction(default=None, *, type=<jobcalc.param_types.DeductionsType object>, is_single=False, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for deduction(s) for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

prompt_for_discount(default=None, *, type=<jobcalc.param_types.DiscountsType object>, is_single=False, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for discount(s) for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

prompt_for_empty()[source]

Prompt the user for all the values that are determined to be empty or ‘0’, and add them to instance appropriately.

Return type:None
prompt_for_hours(default=None, *, type=<class 'decimal.Decimal'>, is_single=False, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for hour(s) for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

prompt_for_margin(default=None, *, type=<jobcalc.param_types.MarginsType object>, is_single=False, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for margin(s) for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

prompt_for_rate(default=None, *, type=<class 'decimal.Decimal'>, is_single=True, current=None, display_multiple_header=True, display_single_header=True)

Prompt the user for a rate for the calculation.

Parameters:
  • default – Optional value to use as default for no input.
  • current – Optional value to display as the current value.
  • is_single – If input is single or accepts multiple values.
  • type – A type to convert the value(s) to.
  • display_multiple_header – If True then show the multiple value header.
  • display_single_header – If True then show the single value header.
Return type:

PromptResponse

jobcalc.calculate(subtotal='0', margin='0', multiplier='0', deduction='0')[source]

Calculates a total based on the parameters. Returned as a Currency.

Parameters:
  • subtotal (Union[Currency, str]) – An item that can be converted to a Currency to be used for the calculation. This would be the sum of all the job costs, materials, hours, etc.
  • margin (Union[Percentage, str]) – An item that can be converted to a Perentage to be used as the profit margin for the calculation. Default is 0.
  • multiplier (Union[Percentage, str]) – An item that can be converted to a Percentage to be used as a percentage discount in the calculation. This discount comes off after the profit margin has been calculated. Default is 0.
  • deduction (Union[Currency, str]) – An item that can be converted to a Currency to be used as a monetary discount in the calculation. This comes off after the profit margin has be calculated and any other percentage discounts have been taken off.
Return type:

Currency

class jobcalc.Context(subtotal, margin, discount, deduction)

A namedtuple that represents the args for the calculate() function.

If these values are set properly then you can call calculate(*context). and the values will be unpacked in the correct order.

Parameters:
  • subtotal – The subtotal for the calculation.
  • margin – The margin for the calculation
  • discount – The percentage discount for the calculation.
  • deduction – The monetary deduction for the calculation.

Example:

>>> ctx = Context(subtotal='123', margin='50', discount='10',
...               deduction='0')
>>> calculate(*ctx).formatted_string()
'$221.40'
jobcalc.PromptResponse

A namedtuple that represents the response to prompting for user input.

Parameters:
  • value – The parsed value from the user input.
  • multiple_heading_displayed – A boolean that indicates if we displayed the multiple value heading during a prompt.
  • single_heading_displayed – A boolean that indicates if we displayed the single value heading during a prompt.

alias of PromptRespone

The following iterms are not imported into the jobcalc namespace, and need to be imported directly from jobcalc.core.

class jobcalc.core.ColorKey(margins, discounts, hours, rate, deductions, costs)

A namedtuple that can be used to declare colors to be used when prompting for user input.

Note

See colorclass for valid colors.

Parameters:
  • margins – Color when prompting for margin.
  • discounts – Color when prompting for discounts.
  • hours – Color when prompting for hours.
  • rate – Color when prompting for rate.
  • deductions – Color when prompting for deductions.
  • costs – Color when prompting for costs.
core.DEFAULT_COLOR_KEY = ColorKey(margins='blue', discounts='yellow', hours='magenta', rate='cyan', deductions='red', costs='green')

Config

The following items are found in the jobcalc.config module, but are also loaded into the jobcalc namespace.

class jobcalc.Config(*, seperator=None, divider=None, rate=None, default_hours=None, margins=None, discounts=None, deductions=None, debug=None)[source]

The main config class that holds common varibles that are used to set up a calculator instance. These variables can either be passed in or retrieved from their corresponding environment variable.

Parameters:
  • seperator (Optional[str]) – A seperator used to seperate key, value pairs parsed from an environment variable. Defaults to ';'. Can be set by JOBCALC_SEPERATOR. (ex. ‘key1:value1;key2:value2;’)
  • divider (Optional[str]) – Used to divide a key, value pair parsed from an environment variable. Defaults to ':'. Can be set by JOBCALC_DIVIDER. (ex. ‘key1:value1’)
  • rate (Optional[str]) – An hourly rate to be used in calculations. Defaults to ‘0’. Can be set by JOBCALC_RATE.
  • default_hours (Optional[str]) – Hours to always be used for a calculation. Defaults to '0'. Can be set by JOBCALC_DEFAULT_HOURS.
  • margins (Optional[Dict]) – A dict with named margins that can be used in a calculation. Defaults to {}. Can be set by JOBCALC_MARGINS using the seperator and divider to distinguish the key, value pairs. All values will get converted to a Percentage to be used as a profit margin. (ex: ‘fifty:50;forty:40’).
  • discounts (Optional[Dict]) – A dict with named discounts that can be used in a calculation. Defaults to {}. Can be set by JOBCALC_DISCOUNTS using the seperator and divider to distinguish the key, value pairs. All values will get converted to a Percentage to be used as a percentage discount. (ex. ‘standard:10;deluxe:15’).
  • deductions (Optional[Dict]) – A dict with named deductions that can be used in a calculation. Defaults to {}. Can be set by JOBCALC_DEDUCTIONS using the seperator and divider to distinguish key, value pairs. All values will get converted to a Currency to be used as a monetary deduction. (ex. ‘one:100;two:200’)
  • debug (Optional[bool]) – A bool to put calculator into debug mode. Defaults to False.
Return type:

None

class jobcalc.TerminalConfig(*, prompt=None, suppress=None, formula=None, allow_empty=None, prompt_seperator=None, **kwargs)[source]

Extends Config with command line interface specific variables.

Note

Boolean envrionment variable’s will be determined as True with any of the following values. Anything else is False.

  • ‘True’
  • ‘TrUe’ (any combination upper-lower works)
  • ‘1’
Parameters:
  • prompt (Optional[bool]) – A bool that if True will call the prompt-all sub-command if the main (job-calc) command is called without a sub-command. If False then we show the help doc. Default is False. Can be set by JOBCALC_PROMPT.
  • suppress (Optional[bool]) – A bool that if True will suppress the detailed table output for any commands called. Default is False. Can be set by JOBCALC_SUPPRESS.
  • formula (Optional[bool]) – A bool that if True will show the formula string for any commands called. Default is False. Can be set by JOBCALC_FORMULA.
  • allow_empty (Optional[bool]) – A bool that if True will not prompt for empty values before performing any calculations. Can be set by JOBCALC_ALLOW_EMPTY.
  • prompt_seperator (Optional[str]) – A string that is used to seperate items that can be multiple values if prompted for. Defaults to ' '. Can be set by JOBCALC_PROMPT_SEPERATOR.
Return type:

None

setup_env()[source]

Set’s up the environment and exposes values to the environment that are needed by other external methods.

This will not override any values that are already set in the environment.

This is useful if the config is loaded from a file.

Return type:None

The following items are not imported into the jobcalc namespace, and need to be imported directly from jobcalc.config.

jobcalc.config.ENV_PREFIX = 'JOBCALC'

The prefix to use for all environment variables.

jobcalc.config.CURRENCY_FORMAT = 'USD'

The currency format to use when formatting a currency string. Should be a valid format used by babel.numbers.format_currency.

This can be set by the JOBCALC_CURRENCY_FORMAT environment variable. Defaults to 'USD'.

jobcalc.config.LOCALE = 'en_US'

The default locale to set for formatting a currency string. Should be a valid locale used by babel.numbers.format_currency.

This can be set by the JOBCALC_CURRENCY_FORMAT environment variable. Defaults to 'en_US'.

jobcalc.config.env_strings = _EnvStrings(seperator='JOBCALC_SEPERATOR', divider='JOBCALC_DIVIDER', rate='JOBCALC_RATE', default_hours='JOBCALC_DEFAULT_HOURS', margins='JOBCALC_MARGINS', discounts='JOBCALC_DISCOUNTS', deductions='JOBCALC_DEDUCTIONS', prompt='JOBCALC_PROMPT', allow_empty='JOBCALC_ALLOW_EMPTY', suppress='JOBCALC_SUPPRESS', formula='JOBCALC_FORMULA', prompt_seperator='JOBCALC_PROMPT_SEPERATOR', config='JOBCALC_CONFIG')

A named tuple that holds all the commonly used environment variables. Primarily used to avoid typo’s and make an IDE work better.

Utils

The following items are found in the jobcalc.utils module, but are also loaded into the jobcalc namespace.

jobcalc.bool_from_env_string(string)[source]

Convert a string recieved from an environment variable into a bool.

‘true’, ‘TRUE’, ‘TrUe’, 1, ‘1’ = True

Everything else is False.

Parameters:string (str) – The string to convert to a bool.
Return type:bool
jobcalc.ensure_callback(callback, error=True)[source]

Ensures that a callback is callable. Either raising errors or returning a valid callback.

If error is False and the callback is not callable, then we return a callable that takes a single value as input and returns that same value.

Parameters:
  • callback (Callable) – The callback to check.
  • error (bool) – If True, raise a NotCallableError if the callback is not callable. If False we will return a valid callback, rather than error. Default is True.
Raises:

NotCallableError – If the callback is not callable and error is True.

Return type:

Callable

jobcalc.dict_from_env_string(string, seperator=None, divider=None, type=None)[source]

Creates a dict from a string, using a seperator to seperate the items and a divider to distinguish key, value pairs.

Parameters:
  • string (Union[str, dict]) – The string to create the dict from.
  • seperator (Optional[str]) – The seperator to use to seperate items in the string. Defaults to ';'. This can also be set by the environment variable JOBCALC_SEPERATOR.
  • divider (Optional[str]) – Divides key, value pairs. Defaults to ':'. This can also be set by the environment variable JOBCALC_DIVIDER.
  • type (Optional[Callable]) – Callback to use to convert all the values to a certain type.

Example:

>>> dict_from_env_string('standard:5;deluxe:10;premium:15')
{'standard': '5', 'deluxe': '10', 'premium': '15'}
>>> dict_from_env_string('standard:5;deluxe:10;premium:15',
...                      type=Percentage)
{'standard': Percentage('0.5'), 'deluxe': Percentage('0.1'),
 'premium': Percentage('0.15')}
Return type:Dict
jobcalc.parse_input_string(string, seperator=';', convert=None)[source]

Parses an input string that could have multiple values passed in from the command line.

Note

This method always returns a tuple, which can be of length 1 or more.

Parameters:
  • string (str) – The input string to parse.
  • seperator (str) – The seperator used to seperate items. Defaults to ';'.
  • convert (Optional[Callable]) – A callback that can be used to convert all the parsed values to a type. This can be a callable that recieves a single value and returns a single value, or we can also handle click.ParamType‘s. Default is None.

Example:

>>> parse_input_string('123;456')
('123', '456')
>>> parse_input_string('123;456', convert=Currency)
(Currency('123'), Currency('456'))
>>> parse_input_string('123')
('123', )
Return type:Tuple[Any]
jobcalc.flatten(*args, *, ignoretypes=<class 'str'>)[source]

A generator to flatten iterables, containing single items and possible other iterables into a single iterable.

Parameters:
  • args – Any value to check for sub-lists (iterable) and flatten.
  • ignoretypes (Any) – A type or tuple of types to ignore (not flatten). Default is str.

Example:

>>> list(flatten([1, 2, [3, 4], [5, [6, 7], [8, 9]]]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> mylist = ['1', '2', [3, ['4'], ['5 is alive', 6], 7], [8, '9.0']]
>>> list(flatten(mylist))
['1', '2', 3, '4', '5 is alive', 6, 7, 8, '9.0']
>>> list(flatten([1, 2, (3, 4, 5)], ignoretypes=tuple))
[1, 2, (3, 4, 5)]
jobcalc.colorize(string, color)[source]

Returns a colorized string.

See also

colorclass

Parameters:
  • string (str) – The string to colorize.
  • color (str) – The color for the string.

Example:

>>> colorize('some string', 'red')
Color('some string')
Return type:Color

Exceptions

The following items can be found in the jobcalc.exceptions module, but are also loaded into the jobcalc namespace.

exception jobcalc.JobCalcError(msg=None)[source]

Base exception used by the app. All custom exceptions should inherit from this class.

Return type:None
exception jobcalc.InvalidEnvString(msg=None)[source]

Raised if parsing an environment string into a dict fails.

Return type:None
exception jobcalc.EnvDictNotFound(msg=None)[source]

Raised if an env string is expected to return a dict, but was not found.

Return type:None
exception jobcalc.NotCallableError(type=None)[source]

Raised if an expected type is supposed to be callable, but is not.

Return type:None
exception jobcalc.PercentageOutOfRange(value)[source]

Raised if percentage is above 100 or less than 0.

Return type:None
exception jobcalc.NotIterableError(msg=None)[source]

Raised if an iterable is expected, but not recieved.

Return type:None
exception jobcalc.InvalidFormatter(msg=None)[source]

Raised if an invalid formatter is found during calculations.

Return type:None
exception jobcalc.HourlyRateError(msg=None)[source]

Raised if an hourly rate is expected, but not found or 0, during calculations.

Return type:None

Formatters

The following items can be found in the jobcalc.formatters module, but are also loaded into default jobcalc namespace.

class jobcalc.BaseFormatter[source]

All formatter’s should sub-class this object, and override the render() method.

static colorize(color)[source]

If an item is a Currency or Percentage, then call it’s formatted_string method, before colorizing the value.

Parameters:
  • item (Any) – A string, Currency, or Percentage to colorize.
  • color (str) – The color to use on the item.
Return type:

Color

static render()[source]

The method all sub-classes should override to render a calculator.

Raises:NotImplementedError – If a sub-class does not implement this method.
Return type:str
static totaled_ctx()[source]

A context manager that yields the TotaledContext for a calculator.

Return type:TotaledContext
class jobcalc.BasicFormatter[source]

A basic formatter that renders the total as a formatted string.

static render()[source]

Return the total as formatted currency string.

Return type:str
class jobcalc.TerminalFormatter(*colors, *, title='DETAILED', no_colors=False, color_header=False)[source]

A terminaltables.AsciiTable, that supports colors and a title.

Parameters:
  • colors – A 5 tuple or ColorContext of strings that can be used by to convert an item to a colorclass.Color. Defaults to (subtotal=’magenta’, margin=’blue’, discount=’yellow’, deduction=’red’, total=’green’).
  • title (str) – A title for the table. Defaults to 'DETAILED'. If you do not want a title, then this can be set to None
  • no_colors (bool) – If True, turns off colored output for the table. Default is False.
  • color_header (bool) – If True then colorize the header as well. Default is False.
render(calculator)[source]

Set’s up the table, and returns it as a string, to be rendered.

Parameters:calculator (Any) – The calculator to create a table for. Should be a BaseCalculator or sub-class.
Return type:str
class jobcalc.FormulaFormatter(*colors, *, formula_string=None, no_color=False, title='FORMULA')[source]

Prints the formula used for the calculations.

Parameters:
  • colors – A 5 tuple or ColorContext of strings that can be used by to convert an item to a colorclass.Color. Defaults to (subtotal=’magenta’, margin=’blue’, discount=’yellow’, deduction=’red’, total=’green’).
  • formula_string (Optional[str]) – A string to use for the format. This should be a a string that we call format, that accepts kwargs (header, subtotal, margin, discount, deduction, and total). Defaults to DEFAULT_FORMULA_STRING.
  • no_color (bool) – Turns colored output off.
  • title (str) – Title to display before the output.
Raises:

TypeError – If colors is not a 5 tuple.

Return type:

None

render(calculator)[source]

Render a formula string used for a BaseCalculator instance or sub-class.

Parameters:calculator (Any) – A BaseCalculator or sub-class to use as the context for the output.
Return type:str

The following items can be imported from the jobcalc.formatters module.

class jobcalc.formatters.ColorContext(subtotal, margin, discount, deduction, total)

A named tuple used to hold colors for items when rendered.

Parameters:
  • subtotal – Color for subtotal’s
  • margin – Color for margin’s
  • discount – Color for discount’s
  • deduction – Color for deduction’s
  • total – Color for total’s
class jobcalc.formatters.TotaledContext(subtotal, margin, discount, deduction, total)

Holds all the values to be rendered by a formatter.

Parameters:
  • subtotal – The subtotal of all the costs, hours, etc. for a calculation.
  • discount – The sum of all the percentage discounts for a calculation.
  • deduction – The sum of all the monetary deductions for a calculation.
  • total – The total of the calculation.
jobcalc.formatters.DEFAULT_COLORS = ColorContext(subtotal='magenta', margin='blue', discount='yellow', deduction='red', total='green')

Default colors to use as the ColorContext.

Param Types

The following items can be imported from jobcalc.param_types module.

class jobcalc.param_types.Percentage[source]

A Decimal sub-class, that handle’s percentages correctly for our app. Adds a formatted_string method for a percentage.

A percentage for our purposes can either be a number between 0 and 100. If the number is between 0 and 1, then it is used as the percentage. If it is above 1 and less than 100, we divide the number by 100 to create or percentage.

Raises:PercentageOutOfRange – If the value is a negative number or 100 or above.

Note

When performing any operations (like addition, multiplication, etc.) to a Percentage, then the new value will need to be converted back to a Percentage for the formatted_string method to work.

Example:

>>> p = Percentage('10')
>>> repr(p)
"Percentage('0.1')"
>>> x = Percentage('10') + Percentage('5')
>>> repr(x)
"Decimal('0.15')"
>>> x.formatted_string()
Traceback ...
AttributeError: 'decimal.Decimal' object has no attribute
'formatted_string'

>>> x = Percentage(Percentage('10') + Percentage('5'))
>>> x.formatted_string()
'15.0%'

10% Example:

>>> Percentage('10').formatted_string()
'10.0%'
>>> Percentage('.1').formatted_string()
'10.0%'
>>> Percentage(
...    Percentage('10').formatted_string()).formatted_string())
'10.0%'
formatted_string()[source]

Return a formatted string for a percentage. Rounded to the first decimal place.

Return type:str
class jobcalc.param_types.Currency[source]

A Decimal sub-class that knows how to handle currency for our app. Adds a formatted_string method to represent a currency instance.

Currency will convert any negative numbers to a positive number, which is what is required by our calculations.

Note

When performing any operations (like addition, multiplication, etc.) to a Currency, then the new value will need to be converted back to a Currency for the formatted_string method to work.

formatted_string()[source]

Return a formatted currency string. This method uses babel.numbers.format_currency using the config.CURRENCY_FORMAT and config.LOCALE variables that are set by the environment or default values. (‘USD’, ‘en_US’).

Example:

>>> Currency('1000').formatted_string()
'$1,000.00'
Return type:str
class jobcalc.param_types.BaseCurrencyType[source]

A custom click.ParamType used to convert values passed on the command line to Currency instances.

convert(value, param, ctx)[source]

The method that does the actual conversion of values. This method is called by click during parsing of input values.

Parameters:
  • value (str) – The value(s) to be converted. These can be either a string, or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Currency, Tuple[Currency]]

class jobcalc.param_types.BasePercentageType[source]

A custom click.ParamType used to convert values passed on the command line to Percentage instances.

convert(value, param, ctx)[source]

The method that does the actual conversion. This method is called directly from click during parsing of input values.

Parameters:
  • value (str) – A single string or iterable of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Percentage

class jobcalc.param_types.DeductionsType[source]

A BaseCurrencyType that is used to convert command line values to Currency instances.

Values can either be single items or multiples seperated ';', if the input is during an option to a command line command or ' ' if the input is during a prompt. These can be changed via environment variables. See config module for more information.

convert(value, param, ctx)[source]

Parses and converts value(s) to Currency instance(s).

Parameters:
  • value (Union[str, Tuple[str]]) – A string or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Currency, Tuple[Currency]]

class jobcalc.param_types.MarginsType[source]

A BasePercentagType that is used to convert command line values to Percentage instances.

Values can either be single items or multiples seperated ';', if the input is during an option to a command line command or ' ' if the input is during a prompt. These can be changed via environment variables. See config module for more information.

convert(value, param, ctx)[source]

Parses and converts value(s) to Percentage instance(s).

Parameters:
  • value (Union[str, Tuple[str]]) – A string or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Percentage, Tuple[Percentage]]

class jobcalc.param_types.DiscountsType[source]

A BasePercentagType that is used to convert command line values to Percentage instances.

Values can either be single items or multiples seperated ';', if the input is during an option to a command line command or ' ' if the input is during a prompt. These can be changed via environment variables. See config module for more information.

convert(value, param, ctx)[source]

Parses and converts value(s) to Percentage instance(s).

Parameters:
  • value (Union[str, Tuple[str]]) – A string or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Percentage, Tuple[Percentage]]

class jobcalc.param_types.CostsType[source]

A BaseCurrencyType that is used to convert command line values to Currency instances.

Values can either be single items or multiples seperated ';', if the input is during an option to a command line command or ' ' if the input is during a prompt. These can be changed via environment variables. See config module for more information.

convert(value, param, ctx)[source]

Parses and converts value(s) to Currency instance(s).

Parameters:
  • value (Union[str, Tuple[str]]) – A string or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Currency, Tuple[Currency]]

class jobcalc.param_types.HoursType[source]

A click.ParamType that is used to convert command line values to decimal.Decimal instances.

Values can either be single items or multiples seperated ';', if the input is during an option to a command line command or ' ' if the input is during a prompt. These can be changed via environment variables. See config module for more information.

convert(value, param, ctx)[source]

Parses and converts value(s) to decimal.Decimal instance(s)

Parameters:
  • value (Union[str, Tuple[str]]) – A string or tuple of strings to convert.
  • param (Any) – The command line parameter this attached to.
  • ctx (Any) – The command line context.
Return type:

Union[Decimal, Tuple[Decimal]]

jobcalc.param_types.parse_input_value(wrapped, instance, args, kwargs)[source]

A decorator to parse the first arg with parse_input_string, before sending on to the wrapped function/method. This method allows multiple values to be passed into a command line option as a single string, split on the default seperator ';'.

Works properly with methods attached to classes or stand alone functions.

Example:

>>> @parse_input_value
... def decorated(values):
...    print(values)
>>> decorated('123;456;')
('123', '456')

>>> class Parsed(object):
...    @parse_input_value
...    def decorated(self, values):
...        print(values)
>>> Parsed().decorated('123;456')
('123', '456')

Note

This method uses parse_input_string method which always returns a tuple, so the parsed value that get’s passed to the wrapped method will always be a tuple, which can be of length 1, if there wasn’t any values to split in the input string.

Example:

>>> @parse_input_value
... def decorated(value):
...   print(value)
>>> decorated('123')
('123', )
jobcalc.param_types.check_env_dict(env_var=None, strict=None)[source]

A decorator to check iterate over the first arg, checking if the values map to a key in an env_dict, returning it’s value if so. Parsing the first arg to a true value. (either the value for the env_dict key or the value itself, if not a key in the env_dict.

This decorator allows command line options to use named parameter’s that are mapped to values in an env_dict.

This will work the same whether wrapping a method attached to a class or a stand alone function.

Parameters:
  • env_var (Optional[str]) – The name of the env_dict to check in.
  • strict (Optional[bool]) – A bool, if True then an error will be raised if an env_dict is not found for env_var. Default is None (False).
Raises:

EnvDictNotFound – If strict is True and an env_dict was not found for env_var.

Example:

$ export JOBCALC_DISCOUNTS='standard:5;deluxe:10;premium:15'
>>> @check_env_dict('JOBCALC_DISCOUNTS')
... def decorated(value):
...    print(value)
>>> decorated('standard')
'5'
>>> decorated('not_in_dict')
'not_in_dict'