csid

Module Contents

This module implements a few classes that together enable a custom case- and space-insensitive dictionary class.

class csid.csid(data=None)

Bases: dict

This is a custom class that overrides lookup functions of dictionary classes. It makes their keys case-insensitive and space-insensitive.

Since this class inherits from the dictionary type, it behaves almost exactly like a dictionary. The main difference is the keys to the dictionary. Any operation with a csid instance will automatically generate and use a csiKeyString for the key if the key is a string type, or a csiKeyDecimal if the key is a float (the hash of a float is not consistent with the hash of a Decimal). Otherwise, the object itself will be used as the key, as other object types should not support spaces nor capitalization.

Constructing a csid instance uses the same syntax as constructing a dictionary, or you can convert an existing dictionary to a csid via csid(dict).

__init__(data=None)

Creates the dictionary. Uses the same construction methods as dict.

If data is specified, each key in data will be converted to a csiKeyDecimal or csiKeyString prior to creating the entry in the csid.

Example usage:

>>> from csid import csid
>>> d = csid()
>>> d[' Nodeset-1'] = 'test'
>>> d[' Nodeset-2'] = 'test2'
>>> print(d)
{
' Nodeset-1': 'test',
' Nodeset-2': 'test2'
}

We can also populate the csid using existing data, providing it’s in a format which can be used to create a dict:

>>> l = [['Nodeset-1', 1],['Nodeset-2', 2],['Nodeset-3', 3]]
>>> csid(l)
csid(csiKeyString('Nodeset-1'): 1, csiKeyString('Nodeset-2'): 2, csiKeyString('Nodeset-3'): 3)

If data is not formatted properly, a TypeError or ValueError will be raised:

>>> csid([['Nodeset-1', 'Nodeset-2', 'NodeSet-3'], [1, 2, 3]])
Traceback (most recent call last):
    ...
ValueError: too many values to unpack (expected 2)
>>> csid([1,2,3])
Traceback (most recent call last):
    ...
TypeError: cannot unpack non-iterable int object

Please note that if two keys in data are identical once they have been made lowercase and had spaces removed, the second entry will overwrite the first one. Example:

>>> csid([['Nodeset-1', 1],['NODESET-1', 2],['Nodeset-3', 3]])
csid(csiKeyString('Nodeset-1'): 2, csiKeyString('Nodeset-3'): 3)
Parameters:

data (iterable) – Defaults to None.

get(key, default=None)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then retrieves the entry in the csid instance using get().

If key is not in the csid, default will be returned.

Example usage:

>>> from csid import csid
>>> d = csid([[100, 1]])
>>> d.get(100)
1

If key is not in the csid, default is returned:

>>> print(d.get(200))
None
Parameters:

key (str, float, Decimal) – The key to the item to retrieve from the dictionary. key will be converted to a csiKeyString or csiKeyDecimal if needed.

Returns:

The value or None.

mergeSubItems(other)

Merges the sub-items of other into the appropriate item in d (the csid instance).

For k and v in other.items(), if d[k] is not defined, set d[k] to v. If d[k] is a list, perform d[k].extend(v). If d[k] is a dictionary, perform d[k].update(v).

This function is meant for cases where update() won’t be sufficient. For example, if d and other both have a key k, the content of each is a list, and you wish the value associated with k to be a list containing the contents of both entries.

Example usage:

>>> from csid import csid
>>> d = csid([[1, [1,2,3]]])
>>> d2 = csid([[1, [4,5,6]]])
>>> d.mergeSubItems(d2)
>>> d
csid(1: [1, 2, 3, 4, 5, 6])

If we just try to update the csid with the other dictionary, we would instead get this behavior:

>>> d = csid([[1, [1,2,3]]])
>>> d2 = csid([[1, [4,5,6]]])
>>> d.update(d2)
>>> d
csid(1: [4, 5, 6])
Parameters:

other (dict) – Other should be a dictionary structure where the values of each item in other are lists or dictionaries. Example: other = {key: {sub-key1: value1, sub-key2: value2}}

pop(key)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then retrieves the entry in the csid instance and removes it using dict.pop().

Example

>>> from csid import csid
>>> d = csid([['a', 1], ['b', 2], ['c', 3]])
>>> d.pop('a')
1
>>> d
csid(csiKeyString('b'): 2, csiKeyString('c'): 3)

This will raise a KeyError if key is not in the csid:

>>> d.pop('a')
Traceback (most recent call last):
    ...
KeyError: csiKeyString('a')
Returns:

The value at key. The key, value pair is removed from the csid.

setdefault(key, default=None)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then retrieves the entry in the csid instance. If key is not in the csid, insert key with a value of default and return default.

If key is in the csid, this simply retrieves its value:

>>> from csid import csid
>>> d = csid([['a', 1]])
>>> d.setdefault('a')
1

If key is not in the csid, this will insert key and set the value to default:

>>> d.setdefault('b', 2)
2
>>> d
csid(csiKeyString('a'): 1, csiKeyString('b'): 2)
Parameters:
  • key (str, float, Decimal) – The key for which to retrieve or set a value. key will be converted to a csiKeyString or csiKeyDecimal if necessary.

  • default – The value which will be inserted into the csid for key if key is not already in the csid. Defaults to None.

Returns:

The value mapped to key, or default if key was not in the csid.

update(other)

If other is not a csid, converts it to one, and then calls update() using the csid of other.

Example usage:

>>> from csid import csid
>>> d = csid([['a', 1]])
>>> d.update([['b', 2]])
>>> d
csid(csiKeyString('a'): 1, csiKeyString('b'): 2)

This function operates more quickly if other is already a csid, although the end result will be the same:

>>> d.update(csid([['c', 3]]))
>>> d
csid(csiKeyString('a'): 1, csiKeyString('b'): 2, csiKeyString('c'): 3)
Parameters:

other (iterable) – An iterable which is a dict type or can be used to construct a csid.

__contains__(key)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then checks if key is in the csid instance.

Here’s an example where we create a csid from a dictionary which uses an int as the key, and then we test if an inpInt with a value of the int is a key in the csid:

>>> from csid import csid
>>> from inpInt import inpInt
>>> from decimal import Decimal
>>> d = csid({25: 'int', 'A1': 'str', 1.234: 'float'})
>>> inpInt('  25') in d
True
>>> 'A1' in d
True
>>> Decimal('1.234') in d
True

If key is not in the csid, this will of course return False. The following example illustrates this, along with the fact that creating a Decimal directly from a float inherits the float inaccuracy:

>>> Decimal(1.234) in d
False
Returns:

True if key in d else False.

Return type:

bool

__delitem__(key)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then deletes the entry in the csid instance.

Example

>>> from csid import csid
>>> d = csid([['a', 1], ['b', 2], ['c', 3]])
>>> del d['C']
>>> d
csid(csiKeyString('a'): 1, csiKeyString('b'): 2)

If key is not defined in the csid, this will raise a KeyError as expected:

>>> del d['D']
Traceback (most recent call last):
    ...
KeyError: csiKeyString('D')
__getitem__(key)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then retrieves the entry in the csid instance. Reference: __getitem__().

Example

>>> from csid import csid
>>> d = csid([['a', 1], ['b', 2], ['c', 3]])
>>> d['C']
3

If key is not defined in the csid, this will raise a KeyError as expected:

>>> d['D']
Traceback (most recent call last):
    ...
KeyError: csiKeyString('D')
__setitem__(key, value)

Converts key to a csiKeyString or csiKeyDecimal if necessary, and then creates d[key] = value.

Example

>>> from csid import csid
>>> d = csid([['a', 1], ['b', 2], ['c', 3]])
>>> d['d'] = 4
>>> d
csid(csiKeyString('a'): 1, csiKeyString('b'): 2, csiKeyString('c'): 3, csiKeyString('d'): 4)
__repr__()

Produces a string which can reproduce the csid.

Example

>>> from csid import csid
>>> csid([['a', 1], ['b', 2], ['c', 3]])
csid(csiKeyString('a'): 1, csiKeyString('b'): 2, csiKeyString('c'): 3)
__str__()

Creates a string for the csid where each (key, value) pair is on its own line.

Example

>>> from csid import csid
>>> print(csid([['a', 1], ['b', 2], ['c', 3], [4, 'd']]))
{
'a': 1,
'b': 2,
'c': 3,
4: 'd'
}
__weakref__

list of weak references to the object (if defined)

class csid.csiKeyString(key)

Bases: str

Creates a key derived from a string instance for csid.

__init__(key)

Sets the key attr.

Example

>>> from csid import csiKeyString
>>> csiKeyString('  Nodeset-1')
csiKeyString('  Nodeset-1')

key should be a string. Other types will raise an AttributeError when the other functions of this class are called. Example:

>>> a = csiKeyString(100)
>>> hash(a)
Traceback (most recent call last):
    ...
AttributeError: 'int' object has no attribute 'lower'

key is not automatically converted to a string for performance reasons. Therefore, if the user needs to use this class directly, they must first ensure that key is a string before instancing it.

Parameters:

key (str) – An instance of a string object to serve as the case- and space-insensitive key.

key

A string type object.

Type:

str

__hash__()

Hashes rsl(key).

Strings which differ only in capitalization and spacing will hash to the same value. For example:

>>> from csid import csiKeyString
>>> hash(csiKeyString('  Nodeset-1')) == hash(csiKeyString('NODESET-1'))
True

Strings which have larger differences will not hash to the same value:

>>> hash(csiKeyString('  Nodeset-1')) == hash(csiKeyString('"NODESET-1"'))
False
Returns:

The hashed value of rsl(key).

Return type:

int

__eq__(other)

Checks if key is equal to other.

other should be a csiKeyString. This function will not convert other to a csiKeyString, because in most cases this class should only be used through a csid, which will handle the conversion.

Parameters:

other (str) – An instance of a string object to which key will be compared.

Returns:

True if rsl(key) == rsl(other), else False.

Return type:

bool

Examples

Here’s the typical usage:

>>> from csid import csiKeyString
>>> csiKeyString('  Nodeset-1') == csiKeyString('Nodeset-1')
True

If other is not a csiKeyString, this will convert other to a csiKeyString before proceeding:

>>> csiKeyString('  Nodeset-1') == 'Nodeset-1'
True
__str__()

Returns str(key).

Example

>>> from csid import csiKeyString
>>> str(csiKeyString('  Nodeset-1'))
'  Nodeset-1'
__repr__()

Returns the string needed to recreate the object.

Example

>>> from csid import csiKeyString
>>> csiKeyString('  Nodeset-1')
csiKeyString('  Nodeset-1')
Returns:

str

__weakref__

list of weak references to the object (if defined)

class csid.csiKeyDecimal(key)

Bases: Decimal

Creates a key derived from a float instance for csid. The key will be a precise Decimal implementation of str(float) as the float is written, as opposed to a Decimal of the evaluated float.

static __new__(key)

If key is a float, convert it to a string before creating the base Decimal instance.

Parameters:

key (float, Decimal, str) – An object which will be converted to a Decimal-type.

Return type:

csiKeyDecimal

__init__(key)

Does nothing by itself. __new__() does the necessary processing to the input.

If key is a float, it will be converted to a Decimal:

>>> from csid import csiKeyDecimal
>>> csiKeyDecimal(1.234)
csiKeyDecimal('1.234')

This also accepts Decimal-types as key:

>>> from inpDecimal import inpDecimal
>>> csiKeyDecimal(inpDecimal(' 1.234'))
csiKeyDecimal('1.234')

Strings are also acceptable keys:

>>> csiKeyDecimal('  1.234')
csiKeyDecimal('1.234')

However, if the string does not evaluate to a Decimal, a decimal.InvalidOperation will be raised:

>>> csiKeyDecimal('  1.234a')
Traceback (most recent call last):
    ...
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
Parameters:

key (float, Decimal, str) – Captures the input from __new__.

__hash__()

Hashes the csiKeyDecimal object.

Example

>>> from csid import csiKeyDecimal
>>> hash(csiKeyDecimal(1.234))
152185638608103802

The hash value will be identical using different input methods to csiKeyDecimal, provided the different input values will evaluate to the same Decimal value:

>>> from inpDecimal import inpDecimal
>>> hash(csiKeyDecimal(inpDecimal('  1.234e0'))) == hash(csiKeyDecimal('  12.34e-1'))
True
Returns:

The hashed value of the csiKeyDecimal object.

Return type:

int

__eq__(other)

Converts other to a csiKeyDecimal (if necessary) and then returns self.as_tuple() == other.as_tuple().

Examples

>>> from csid import csiKeyDecimal
>>> csiKeyDecimal('  12.34e-1') == 1.234
True
>>> csiKeyDecimal('  12.34e-1') == 1.237
False
Parameters:

other (float, Decimal, str) – An instance of a float, Decimal, or str object to which the csiKeyDecimal will be compared.

Returns:

True if self.as_tuple() == other.as_tuple(), else False.

Return type:

bool

__str__()

Returns a string representation of the csiKeyDecimal.

Example

>>> from csid import csiKeyDecimal
>>> str(csiKeyDecimal('  12.34e-1'))
'1.234'
__repr__()

Returns the string needed to recreate the object.

Example

>>> from csid import csiKeyDecimal
>>> csiKeyDecimal('  1.234')
csiKeyDecimal('1.234')
__weakref__

list of weak references to the object (if defined)