You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/Naked/toolshed/types.py

993 lines
44 KiB

#!/usr/bin/env python
# encoding: utf-8
import sys
from Naked.settings import debug as DEBUG_FLAG
#------------------------------------------------------------------------------
# [[ NakedObject class ]]
# A generic Python object
# Assigns object attributes by key name in the dictionary argument to the constructor
# The methods are inherited by other mutable Naked object extension types
# Attribute accessors: hasattr, getattr, setattr, delattr
#------------------------------------------------------------------------------
class NakedObject(object):
# initialize with an attributes dictionary {attribute_name: attribute_value}
def __init__(self, attributes={}, naked_type='NakedObject'):
if len(attributes) > 0:
for key in attributes:
setattr(self, key, attributes[key])
setattr(self, '_naked_type_', naked_type) # maintain an attribute to keep track of the extension type
#------------------------------------------------------------------------------
# [ _getAttributeDict method ] (dictionary)
# returns a dictionary of the NakedObject instance attributes
#------------------------------------------------------------------------------
def _getAttributeDict(self):
return self.__dict__
#------------------------------------------------------------------------------
# [ _equal_type method ] (boolean)
# returns boolean for type of instance == type of test parameter instance
#------------------------------------------------------------------------------
def _equal_type(self, other_obj):
return type(self) == type(other_obj)
#------------------------------------------------------------------------------
# [ _equal_attributes metod ] (method)
# returns boolean for instance.__dict__ == test parameter .__dict__ (attribute comparison)
#------------------------------------------------------------------------------
def _equal_attributes(self, other_obj):
return self.__dict__ == other_obj.__dict__
#------------------------------------------------------------------------------
# == overload
#------------------------------------------------------------------------------
def __eq__(self, other_obj):
return self.equals(other_obj)
#------------------------------------------------------------------------------
# != overload
#------------------------------------------------------------------------------
def __ne__(self, other_obj):
result = self.equals(other_obj)
if result:
return False # reverse result of the equals method
else:
return True
#------------------------------------------------------------------------------
# [ equals method ] (boolean)
# equality testing based on type and attributes
# **NEED TO OVERRIDE IN CLASSES THAT INHERIT
#------------------------------------------------------------------------------
def equals(self, other_obj):
return self._equal_type(other_obj) and self._equal_attributes(other_obj)
#------------------------------------------------------------------------------
# [ type method ] (string)
# returns the Naked type extension string that is set in the constructor for each object type
#------------------------------------------------------------------------------
def type(self):
if hasattr(self, '_naked_type_'):
return self._naked_type_
else:
return None
#------------------------------------------------------------------------------
# [[ XDict class ]]
# An inherited extension to the dictionary type
#------------------------------------------------------------------------------
class XDict(dict, NakedObject):
def __init__(self, dict_obj, attributes={}, naked_type='XDict'):
dict.__init__(self, dict_obj)
NakedObject.__init__(self, attributes, naked_type)
#------------------------------------------------------------------------------
# XDict Operator Overloads
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# + overload
# overwrites existing keys with key:value pairs from new dictionaries if they are the same keys
# returns the updated XDict object
#------------------------------------------------------------------------------
def __add__(self, other_dict):
try:
self.update(other_dict)
if hasattr(other_dict, '_naked_type_') and (getattr(other_dict, '_naked_type_') == 'XDict'):
attr_dict = other_dict._getAttributeDict() # get the attributes from the parameter XDict and add to new XDict
if len(attr_dict) > 0:
for key in attr_dict:
setattr(self, key, attr_dict[key])
return self
except Exception as e:
if DEBUG_FLAG:
sys.stderr.write("Naked Framework Error: unable to combine XDict with parameter provided (Naked.toolshed.types.py)")
raise e
#------------------------------------------------------------------------------
# +- overload
# overwrites existing keys with another_dict (right sided argument) keys if they are the same keys
# returns the updated XDict object
#------------------------------------------------------------------------------
def __iadd__(self, other_dict):
try:
self.update(other_dict)
if hasattr(other_dict, '_naked_type_') and (getattr(other_dict, '_naked_type_') == 'XDict'):
attr_dict = other_dict._getAttributeDict() # get the attributes from the parameter XDict and add to new XDict
if len(attr_dict) > 0:
for key in attr_dict:
setattr(self, key, attr_dict[key])
return self
except Exception as e:
if DEBUG_FLAG:
sys.stderr.write("Naked Framework Error: unable to combine XDict with parameter provided (Naked.toolshed.types.py)")
raise e
#------------------------------------------------------------------------------
# == overload
#------------------------------------------------------------------------------
def __eq__(self, other_obj):
return self.equals(other_obj)
#------------------------------------------------------------------------------
# != overload
#------------------------------------------------------------------------------
def __ne__(self, other_obj):
result = self.equals(other_obj)
if result:
return False # reverse result of the equals method
else:
return True
#------------------------------------------------------------------------------
# [ equals method ] (boolean)
# tests for equality of the XDict (type, attributes, dictionary equality)
#------------------------------------------------------------------------------
def equals(self, other_obj):
if self._equal_type(other_obj) and self._equal_attributes(other_obj):
if dict(self) == dict(other_obj):
return True
else:
return False
else:
return False
#------------------------------------------------------------------------------
# XDict Value Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ conditional_map_to_vals method ] (XDict)
# returns the original XDict with values that meet True condition in `conditional_function`
# modified as per the `mapped_function` with single value argument call
# Test: test_xdict_conditional_map
#------------------------------------------------------------------------------
def conditional_map_to_vals(self, conditional_function, mapped_function):
for key, value in self.xitems():
if conditional_function(key):
self[key] = mapped_function(value)
return self
#------------------------------------------------------------------------------
# [ map_to_vals method ] (XDict)
# returns the original XDict with all values modified as per the `mapped_function`
# Test: test_xdict_map_to_vals
#------------------------------------------------------------------------------
def map_to_vals(self, mapped_function):
# return XDict( zip(self, map(mapped_function, self.values())), self._getAttributeDict() ) - slower in Py2
for key, value in self.xitems():
self[key] = mapped_function(value)
return self
#------------------------------------------------------------------------------
# [ val_xlist method ] (XList)
# return an XList of the values in the XDict
# Test: test_xdict_val_xlist
#------------------------------------------------------------------------------
def val_xlist(self):
return XList(self.values(), self._getAttributeDict())
#------------------------------------------------------------------------------
# [ max_val method ] (tuple of maximum value and associated key)
# Test: test_xdict_max_val, test_xdict_max_val_strings (strings are alphabetic if not numerals)
#------------------------------------------------------------------------------
def max_val(self):
return max(zip(self.values(), self.keys()))
#------------------------------------------------------------------------------
# [ min_val method ] (tuple of minimum value and associated key)
#------------------------------------------------------------------------------
def min_val(self):
return min(zip(self.values(), self.keys()))
#------------------------------------------------------------------------------
# [ sum_vals method ] (numeric return type dependent upon original value type)
# returns sum of all values in the dictionary
#------------------------------------------------------------------------------
def sum_vals(self):
return sum(self.values())
#------------------------------------------------------------------------------
# [ val_count method ] (integer)
# returns an integer value for the total count of `value_name` in the dictionary values
# Case sensitive test if comparing strings
# Tests: test_xdict_val_count_string, test_xdict_val_count_integer
#------------------------------------------------------------------------------
def val_count(self, value_name):
count = 0
for test_value in self.values():
if value_name == test_value:
count += 1
return count
#------------------------------------------------------------------------------
# [ value_count_ci method ] (integer)
# returns an integer value for the total count of case insensitive `value_name`
# strings/char in the dictionary values. Can include non-string types (ignores them)
# Test: test_xdict_val_count_ci
#------------------------------------------------------------------------------
def val_count_ci(self, value_name):
count = 0
for test_value in self.values():
try:
if value_name.lower() in test_value.lower():
count += 1
except AttributeError: # the test_value was not a string, catch exception and continue count attempt
continue
return count
#------------------------------------------------------------------------------
# XDict Key Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ difference method ] (difference set of keys)
# definition: keys that are included in self, but not in `another_dict`
# Tests: test_xdict_key_difference, test_xdict_key_difference_when_none_present
#------------------------------------------------------------------------------
def difference(self, another_dict):
return set(self.keys()) - set(another_dict.keys())
#------------------------------------------------------------------------------
# [ intersection method ] (intersection set of keys)
# definition: keys that are included in both self and `another_dict`
# Tests: test_xdict_key_intersection, test_xdict_key_intersection_when_none_present
#------------------------------------------------------------------------------
def intersection(self, another_dict):
return set(self.keys()) & set(another_dict.keys())
#------------------------------------------------------------------------------
# [ key_xlist method ] (XList)
# returns an XList of the keys in the XDict
# Test: test_xdict_key_xlist
#------------------------------------------------------------------------------
def key_xlist(self):
return XList(self.keys(), self._getAttributeDict())
#------------------------------------------------------------------------------
# [ random method ] (dictionary)
# return new Python dictionary with single, random key:value pair
# Test: test_xdict_key_random
#------------------------------------------------------------------------------
def random(self):
import random
from Naked.toolshed.python import py_major_version
random_key_list = random.sample(self.keys(), 1)
the_key = random_key_list[0]
return {the_key: self[the_key]}
#------------------------------------------------------------------------------
# [ random_sample method ] (dictionary)
# return new Python dictionary with `number_of_items` random key:value pairs
# Test: test_xdict_key_random_sample
#------------------------------------------------------------------------------
def random_sample(self, number_of_items):
import random
random_key_list = random.sample(self.keys(), number_of_items)
new_dict = {}
for item in random_key_list:
new_dict[item] = self[item]
return new_dict
#------------------------------------------------------------------------------
# [ xitems method ] (tuple)
# Generator method that returns tuples of every key, value in dictionary
# uses appropriate method from Python 2 and 3 interpreters
# Test: test_xdict_xitems
#------------------------------------------------------------------------------
def xitems(self):
from Naked.toolshed.python import py_major_version
if py_major_version() > 2:
return self.items()
else:
return self.iteritems()
#------------------------------------------------------------------------------
# [[ XList class ]]
# An inherited extension to the list object that permits attachment of attributes
#------------------------------------------------------------------------------
class XList(list, NakedObject):
def __init__(self, list_obj, attributes={}, naked_type='XList'):
list.__init__(self, list_obj)
NakedObject.__init__(self, attributes, naked_type)
#------------------------------------------------------------------------------
# XList Operator Overloads
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# + operator overload
# extends XList with one or more other lists (`*other_lists`)
#------------------------------------------------------------------------------
def __add__(self, *other_lists):
try:
for the_list in other_lists:
# add attributes if it is an XList
if hasattr(the_list, '_naked_type_') and (getattr(the_list, '_naked_type_') == 'XList'):
attr_dict = the_list._getAttributeDict() # get XList attribute dictionary
if len(attr_dict) > 0:
for key in attr_dict:
setattr(self, key, attr_dict[key])
# extend the XList items
self.extend(the_list)
return self
except Exception as e:
if DEBUG_FLAG:
sys.stderr.write("Naked Framework Error: unable to combine XList with parameter provided (Naked.toolshed.types.py)")
raise e
#------------------------------------------------------------------------------
# += overload
# extends XList with one other list (`another_list`)
#------------------------------------------------------------------------------
def __iadd__(self, another_list):
try:
#add attributes if it is an XList
if hasattr(another_list, '_naked_type_') and (getattr(another_list, '_naked_type_') == 'XList'):
attr_dict = another_list._getAttributeDict() # get XList attribute dictionary
if len(attr_dict) > 0:
for key in attr_dict:
setattr(self, key, attr_dict[key])
# extend the XList items
self.extend(another_list)
return self
except Exception as e:
if DEBUG_FLAG:
sys.stderr.write("Naked Framework Error: unable to combine XList with parameter provided (Naked.toolshed.types.py)")
raise e
#------------------------------------------------------------------------------
# == overload
#------------------------------------------------------------------------------
def __eq__(self, other_obj):
return self.equals(other_obj)
#------------------------------------------------------------------------------
# != overload
#------------------------------------------------------------------------------
def __ne__(self, other_obj):
result = self.equals(other_obj)
if result:
return False # reverse result of the equals method
else:
return True
#------------------------------------------------------------------------------
# [ equals method ] (boolean)
# tests for equality of the XList (type, attributes, list equality)
#------------------------------------------------------------------------------
def equals(self, other_obj):
if self._equal_type(other_obj) and self._equal_attributes(other_obj):
if list(self) == list(other_obj):
return True
else:
return False
else:
return False
#------------------------------------------------------------------------------
# XList Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# XList String Methods
#------------------------------------------------------------------------------
# [ join method ] (string)
# Concatenate strings in the list and return
# Default separator between string list values is an empty string
# Pass separator character(s) as an argument to the method
#------------------------------------------------------------------------------
def join(self, separator=""):
return separator.join(self)
#------------------------------------------------------------------------------
# [ postfix method ] (list of strings)
# Append a string to each list item string
#------------------------------------------------------------------------------
def postfix(self, after):
return [ "".join([x, after]) for x in self ]
#------------------------------------------------------------------------------
# [ prefix method ] (list of strings)
# Prepend a string to each list item string
#------------------------------------------------------------------------------
def prefix(self, before):
return [ "".join([before, x]) for x in self ]
#------------------------------------------------------------------------------
# [ surround method ] (list of strings)
# Surround each list item string with a before and after string argument passed to the method
#------------------------------------------------------------------------------
def surround(self, before, after=""):
if after == "":
after = before
return [ "".join([before, x, after]) for x in self ]
#------------------------------------------------------------------------------
# XList Numeric Methods
#------------------------------------------------------------------------------
# [ max method ] (list dependent type, single value)
# return maximum value from the list items
#------------------------------------------------------------------------------
def max(self):
return max(self)
#------------------------------------------------------------------------------
# [ min method ] (list dependent type, single value)
# return minimum value from the list items
#------------------------------------------------------------------------------
def min(self):
return min(self)
#------------------------------------------------------------------------------
# [ sum method ] (list dependent type, single value)
# return the sum of all list items
#------------------------------------------------------------------------------
def sum(self):
return sum(self)
#------------------------------------------------------------------------------
# XList Data Management Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ count_duplicates method ] (integer)
# returns an integer count of number of duplicate values
#------------------------------------------------------------------------------
def count_duplicates(self):
return len(self) - len(set(self))
#------------------------------------------------------------------------------
# [ remove_duplicates ] (XList)
# returns a new XList with duplicates removed
#------------------------------------------------------------------------------
def remove_duplicates(self):
return XList( set(self), self._getAttributeDict() )
#------------------------------------------------------------------------------
# [ difference method ] (set)
# returns a set containing items in XList that are not contained in `another_list`
#------------------------------------------------------------------------------
def difference(self, another_list):
return set(self) - set(another_list)
#------------------------------------------------------------------------------
# [ intersection method ] (set)
# returns a set containing items that are in both XList and `another_list`
#------------------------------------------------------------------------------
def intersection(self, another_list):
return set(self) & set(another_list)
#------------------------------------------------------------------------------
# XList Function Mapping Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ map_to_items method ] (XList)
# returns original XList with modification of each item based upon `mapped_function`
#------------------------------------------------------------------------------
def map_to_items(self, mapped_function):
# return XList( map(mapped_function, self), self._getAttributeDict() ) - slower
for index, item in enumerate(self):
self[index] = mapped_function(item)
return self
#------------------------------------------------------------------------------
# [ conditional_map_to_items method ] (XList)
# returns original XList with modification of items that meet True condition in
# `conditional_function` with change performed as defined in `mapped_function`
#------------------------------------------------------------------------------
def conditional_map_to_items(self, conditional_function, mapped_function):
for index, item in enumerate(self):
if conditional_function(item):
self[index] = mapped_function(item)
return self
#------------------------------------------------------------------------------
# XList Descriptive Stats Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ count_ci method ] (integer)
# returns an integer count of the number of case-insensitive items that match `test_string`
#------------------------------------------------------------------------------
def count_ci(self, test_string):
count = 0
for item in self:
try:
if test_string.lower() in item.lower():
count += 1
except AttributeError: # the test_value was not a string, catch exception and continue count attempt
continue
return count
#------------------------------------------------------------------------------
# [ random method ] (list)
# returns a single item list with a random element from the original XList
#------------------------------------------------------------------------------
def random(self):
import random
return random.choice(self)
#------------------------------------------------------------------------------
# [ random_sample method ] (list)
# returns a list with one or more random items from the original XList
# number of items determined by the `number_of_items` argument
#------------------------------------------------------------------------------
def random_sample(self, number_of_items):
import random
return random.sample(self, number_of_items)
#------------------------------------------------------------------------------
# [ shuffle method ] (XList)
# randomly shuffle the contents of the list
#------------------------------------------------------------------------------
def shuffle(self):
import random
random.shuffle(self)
return self
#------------------------------------------------------------------------------
# XList Match Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ wildcard_match method ] (list)
# returns a list of items that match the `wildcard` argument
#------------------------------------------------------------------------------
def wildcard_match(self, wildcard):
if hasattr(self, 'nkd_fnmatchcase'):
fnmatchcase = self.nkd_fnmatchcase
else:
from fnmatch import fnmatchcase
self.nkd_fnmatchcase = fnmatchcase
return [ x for x in self if fnmatchcase(x, wildcard) ]
#------------------------------------------------------------------------------
# [ multi_wildcard_match method ] (list)
# returns a list of items that match one or more | separated wildcards passed as string
#------------------------------------------------------------------------------
def multi_wildcard_match(self, wildcards):
if hasattr(self, 'nkd_fnmatchcase'):
fnmatchcase = self.nkd_fnmatchcase
else:
from fnmatch import fnmatchcase
self.nkd_fnmatchcase = fnmatchcase
wc_list = wildcards.split('|')
return_list = []
for wc in wc_list:
temp_list = [ x for x in self if fnmatchcase(x, wc) ]
for result in temp_list:
return_list.append(result)
return return_list
#------------------------------------------------------------------------------
# XList Cast Methods
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# [ xset method ] (XSet)
# return an XSet with unique XList item values and XList attributes
#------------------------------------------------------------------------------
def xset(self):
attr_dict = self._getAttributeDict()
return XSet(set(self), attr_dict)
#------------------------------------------------------------------------------
# [ xfset method ] (XFSet)
# return an XFSet with unique XList item values and XList attributes
#------------------------------------------------------------------------------
def xfset(self):
attr_dict = self._getAttributeDict()
return XFSet(set(self), attr_dict)
#------------------------------------------------------------------------------
# [ xtuple method ] (XTuple)
# returns an XTuple with XList item values and XList attributes
#------------------------------------------------------------------------------
def xtuple(self):
attr_dict = self._getAttributeDict()
return XTuple(tuple(self), attr_dict)
#------------------------------------------------------------------------------
# [[ XMaxHeap class ]]
# max heap queue
#------------------------------------------------------------------------------
from heapq import heappush, heappop
class XMaxHeap(NakedObject):
def __init__(self, attributes={}, naked_type='XMaxHeap'):
NakedObject.__init__(self, attributes, naked_type)
self._queue = []
self._index = 0
# length of the queue
def __len__(self):
return len(self._queue)
# O(log n) complexity
def push(self, the_object, priority):
heappush(self._queue, (-priority, self._index, the_object))
self._index += 1
# O(log n) complexity
def pop(self):
if self._queue:
return heappop(self._queue)[-1]
else:
return None
# push new object and return the highest priority object
def pushpop(self, the_object, priority):
heappush(self._queue, (-priority, self._index, the_object))
self._index += 1
if self._queue:
return heappop(self._queue)[-1]
else:
return None # return None if the queue is empty
# the length of the queue
def length(self):
return len(self._queue)
#------------------------------------------------------------------------------
# [[ XMinHeap class ]]
# min heap queue
#------------------------------------------------------------------------------
from heapq import heappush, heappop
class XMinHeap(NakedObject):
def __init__(self, attributes={}, naked_type='XMinHeap'):
NakedObject.__init__(self, attributes, naked_type)
self._queue = []
self._index = 0
# length of the queue
def __len__(self):
return len(self._queue)
# O(log n) complexity
def push(self, the_object, priority):
heappush(self._queue, (priority, self._index, the_object))
self._index += 1
# O(log n) complexity
def pop(self):
if self._queue:
return heappop(self._queue)[-1]
else:
return None # return None if the queue is empty
# push new object and return the lowest priority object
def pushpop(self, the_object, priority):
heappush(self._queue, (priority, self._index, the_object))
self._index += 1
if self._queue:
return heappop(self._queue)[-1]
else:
return None #return None if the queue is empty
# the length of the queue
def length(self):
return len(self._queue)
#------------------------------------------------------------------------------
# [[ XQueue class ]]
#
#------------------------------------------------------------------------------
from collections import deque
class XQueue(deque, NakedObject):
def __init__(self, initial_iterable=[], attributes={}, max_length=10, naked_type='XQueue'):
deque.__init__(self, initial_iterable, max_length)
NakedObject.__init__(self, attributes, naked_type)
#------------------------------------------------------------------------------
# [[ XSet class ]]
# An inherited extension to the mutable set object that permits attribute assignment
# Inherits from set and from NakedObject (see methods in NakedObject at top of this module
#------------------------------------------------------------------------------
class XSet(set, NakedObject):
def __init__(self, set_obj, attributes={}, naked_type='XSet'):
set.__init__(self, set_obj)
NakedObject.__init__(self, attributes, naked_type)
# += operator overload to extend the XSet with a second set
def __iadd__(self, another_set):
self.update(another_set)
return self
def xlist(self):
attr_dict = self._getAttributeDict()
return XList(list(self), attr_dict)
def xfset(self):
attr_dict = self._getAttributeDict()
return XFSet(self, attr_dict)
#------------------------------------------------------------------------------
# [[ XFSet class ]]
# An inherited extension to the immutable frozenset object that permits attribute assignment
# Immutable so there is no setter method, attributes must be set in the constructor
#------------------------------------------------------------------------------
class XFSet(frozenset):
def __new__(cls, the_set, attributes={}, naked_type="XFSet"):
set_obj = frozenset.__new__(cls, the_set)
if len(attributes) > 0:
for key in attributes:
setattr(set_obj, key, attributes[key])
setattr(set_obj, '_naked_type_', naked_type) # set the naked extension type as an attribute (NakedObject does this for mutable classes)
return set_obj
def _getAttributeDict(self):
return self.__dict__
def xlist(self):
attr_dict = self._getAttributeDict()
return XList(list(self), attr_dict, naked_type="XList")
def xset(self):
attr_dict = self._getAttributeDict()
return XSet(self, attr_dict, naked_type="XSet")
#------------------------------------------------------------------------------
# [ type method ] (string)
# returns the Naked type extension string that is set in the constructor for each object type
#------------------------------------------------------------------------------
def type(self):
if hasattr(self, '_naked_type_'):
return self._naked_type_
else:
return None
#------------------------------------------------------------------------------
# [[ XString class ]]
# An inherited extension to the immutable string object that permits attribute assignment
# Immutable so there is no setter method, attributes must be set in the constructor
# Python 2: byte string by default, can cast to normalized UTF-8 with XString().unicode() method
# Python 3: string (that permits unicode) by default, can normalize with XString().unicode() method
#------------------------------------------------------------------------------
class XString(str):
def __new__(cls, string_text, attributes={}, naked_type='XString'):
str_obj = str.__new__(cls, string_text)
if len(attributes) > 0:
for key in attributes:
setattr(str_obj, key, attributes[key])
setattr(str_obj, '_naked_type_', naked_type)
return str_obj
#------------------------------------------------------------------------------
# [ _getAttributeDict method ] (dictionary)
# returns a dictionary of the XString instance attributes
#------------------------------------------------------------------------------
def _getAttributeDict(self):
return self.__dict__
#------------------------------------------------------------------------------
# [ type method ] (string)
# returns the Naked type extension string that is set in the constructor for each object type
#------------------------------------------------------------------------------
def type(self):
if hasattr(self, '_naked_type_'):
return self._naked_type_
else:
return None
## TODO: see where + vs. join breakpoint becomes important
def concat(self, *strings):
str_list = []
for x in strings:
str_list.append(x)
return "".join(str_list)
# fastest substring search truth test
def contains(self, substring):
return substring in self
# split the string on one or more delimiters, return list
# if up to two chars, then uses str.split(), if more chars then use re.split
def xsplit(self, split_delimiter):
length = len(split_delimiter)
if length > 2:
import re
split_delimiter = "".join([ '[', split_delimiter, ']' ])
return re.split(split_delimiter, self)
elif length > 1:
delim2 = split_delimiter[1]
first_list = self.split(split_delimiter[0])
result_list = []
for item in first_list:
for subitem in item.split(delim2):
result_list.append(subitem)
return result_list
else:
return self.split(split_delimiter)
# split the string on one or more characters and return items in set
def xsplit_set(self, split_delimiter):
return set(self.xsplit(split_delimiter))
# str begins with substring - faster than str.startswith()
def begins(self, begin_string):
return begin_string in self[0:len(begin_string)]
# str ends with substring - faster than str.endswith()
def ends(self, end_string):
return end_string in self[-len(end_string):]
# case sensitive wildcard match on the XString (boolean returned)
def wildcard_match(self, wildcard):
from fnmatch import fnmatchcase
return fnmatchcase(self, wildcard)
# convert string to normalized UTF-8 in Python 2 and 3 (##TODO: convert to XUnicode with attributes?)
def unicode(self):
from sys import version_info
from unicodedata import normalize
if version_info[0] == 2:
return normalize('NFKD', self.decode('UTF-8'))
else:
return normalize('NFKD', self)
# this version works
class XUnicode:
def __init__(self, string_text, attributes={}, naked_type='XUnicode'):
import sys
import unicodedata
norm_text = unicodedata.normalize('NFKD', string_text)
class XUnicode_2(unicode):
def __new__(cls, the_string_text, attributes={}, naked_type='XUnicode2'):
str_obj = unicode.__new__(cls, the_string_text)
if len(attributes) > 0:
for key in attributes:
setattr(str_obj, key, attributes[key])
setattr(str_obj, '_naked_type_', naked_type) # set the type to XUnicode2 for Py 2 strings
return str_obj
class XUnicode_3(str):
def __new__(cls, the_string_text, attributes={}, naked_type='XUnicode3'):
str_obj = str.__new__(cls, the_string_text)
if len(attributes) > 0:
for key in attributes:
setattr(str_obj, key, attributes[key])
setattr(str_obj, '_naked_type_', naked_type) # set the type to XUnicode3 for Py 3 strings
return str_obj
if sys.version_info[0] == 2:
self.obj = XUnicode_2(norm_text, attributes)
self.norm_unicode = norm_text
self.naked_u_string = self.obj.encode('utf-8') # utf-8 encoded byte string
elif sys.version_info[0] == 3:
self.naked_u_string = XUnicode_3(norm_text, attributes).encode('utf-8') # ?
def __str__(self):
# return self.naked_u_string
return self.obj
def __repr__(self):
return self.naked_u_string
def __getattr__(self, the_attribute):
return self.obj.__dict__[the_attribute]
def __cmp__(self, other_string):
return hash(self.naked_u_string) == hash(other_string)
# TODO: add check for same attributes
#------------------------------------------------------------------------------
# [ _getAttributeDict method ] (dictionary)
# returns a dictionary of the NakedObject instance attributes
#------------------------------------------------------------------------------
def _getAttributeDict(self):
return self.__dict__
#------------------------------------------------------------------------------
# [ type method ] (string)
# returns the Naked type extension string that is set in the constructor for each object type
#------------------------------------------------------------------------------
def type(self):
if hasattr(self, '_naked_type_'):
return self._naked_type_
else:
return None
#------------------------------------------------------------------------------
# [[ XTuple class ]]
#
#------------------------------------------------------------------------------
class XTuple(tuple):
def __new__(cls, the_tuple, attributes={}, naked_type='XTuple'):
tup_obj = tuple.__new__(cls, the_tuple)
if len(attributes) > 0:
for key in attributes:
setattr(tup_obj, key, attributes[key])
setattr(tup_obj, '_naked_type_', naked_type)
return tup_obj
#------------------------------------------------------------------------------
# [ _getAttributeDict method ] (dictionary)
# returns a dictionary of the NakedObject instance attributes
#------------------------------------------------------------------------------
def _getAttributeDict(self):
return self.__dict__
#------------------------------------------------------------------------------
# [ type method ] (string)
# returns the Naked type extension string that is set in the constructor for each object type
#------------------------------------------------------------------------------
def type(self):
if hasattr(self, '_naked_type_'):
return self._naked_type_
else:
return None
if __name__ == '__main__':
pass
# no = nobj({"version":"1.0.1", "test":"code"})
# print(no)
# print(no.version)
# print(no.test)
# nl = XList([1, 2, 3, 1, 2, 5], {"version":"1.0.1", "test":"code"})
# print(nl.count_duplicates())
# the_list = list(range(5000))
# nl = XList(the_list)
# nq = XPriorityQueue()
# nq.push('test', 5)
# nq.push('one', 3)
# nq.push('another', 4)
# print(nq.pop())
# print(nq.pop())
# print(nq.pop())
# nl = XList([2, 2, 2, 'another'], {'p': 'attribute'})
# print(nl)
# print(nl.count_item(2))
# nq = XQueue(nl, max_length=2)
# print(nq)
# xs = XSet({'test', 'true', 'false'}, {'bonus': 'candy', 'test': 'another'})
# xs += {'bogus', 'yep'}
# print(xs)
# xd = XDict({'test2': 0, 'is': 1}, {'a': '1', 'b': '2'})
# ad = {'test': 0, 'is': 2}
# ld = xd.intersection(ad)
# print(ld)
# xd = xd + ad + ld
# print(xd.map_to_vals(pr))
# print(xd.a)
# print(xd)
# print(xd.a)
# print(xd.min_val())
# print(xd.conditional_map_to_vals(matcher, resulter))
# nl = XList([ 'test.txt', 'bogus.txt', 'test.py', 'another.rb', 'est.doc', 'est.py' ])
# print(nl.multi_wildcard_match('*.py|*.txt|*.doc'))
# xstr = XString("Hey! Cœur It's Bengali ব য,\nand here is some more ২")
# ustr = xstr.unicode()
# print(isinstance(ustr, bytes))
# print(xstr)