Source code for PythonExtensionsCollection.Utils.CUtils
# **************************************************************************************************************
#
# Copyright 2020-2022 Robert Bosch GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# **************************************************************************************************************
#
# CUtils.py
#
# XC-CT/ECA3-Queckenstedt
#
# 26.01.2022
#
# **************************************************************************************************************
# -- import standard Python modules
from dotdict import dotdict
# **************************************************************************************************************
# wrapper
# **************************************************************************************************************
[docs]def PrettyPrint(oData=None, hOutputFile=None, bToConsole=True, nIndent=0, sPrefix=None, bHexFormat=False):
"""
|
**Function:**
**PrettyPrint**
Wrapper function to create and use a ``CTypePrint`` object. This wrapper function is responsible for
printing out the content to console and to a file (depending on input parameter).
The content itself is prepared by the method ``TypePrint`` of class ``CTypePrint``. This happens ``PrettyPrint`` internally.
The idea behind the ``PrettyPrint`` function is to resolve also the content of composite data types and provide for every parameter inside:
* the type
* the total number of elements inside (e.g. the number of keys inside a dictionary)
* the counter number of the current element
* the value
Example call:
``PrettyPrint(oData)`` (*with oData is a Python variable of any type*)
The output can e.g. look like this:
.. code:: python
[DICT] (3/1) > {K1} [STR] : 'Val1'
[DICT] (3/2) > {K2} [LIST] (4/1) > [INT] : 1
[DICT] (3/2) > {K2} [LIST] (4/2) > [STR] : 'A'
[DICT] (3/2) > {K2} [LIST] (4/3) > [INT] : 2
[DICT] (3/2) > {K2} [LIST] (4/4) > [TUPLE] (2/1) > [INT] : 9
[DICT] (3/2) > {K2} [LIST] (4/4) > [TUPLE] (2/2) > [STR] : 'Z'
[DICT] (3/3) > {K3} [INT] : 5
Every line of output has to be interpreted strictly from left to right.
For example the meaning of the fifth line of output
``[DICT] (3/2) > {K2} [LIST] (4/4) > [TUPLE] (2/1) > [INT] : 9``
is:
* The type of input parameter (``oData``) is ``dict``
* The dictionary contains 3 keys
* The current line gives information about the second key of the dictionary
* The name of the second key is 'K2'
* The value of the second key is of type ``list``
* The list contains 4 elements
* The current line gives information about the fourth element of the list
* The fourth element of the list is of type ``tuple``
* The tuple contains 2 elements
* The current line gives information about the first element of the tuple
* The first element of the tuple is of type ``int`` and has the value 9
Types are encapsulated in square brackets, counter in round brackets and key names are encapsulated in curly brackets.
**Args:**
**oData** (*any Python data type*)
A variable of any Python data type.
**hOutputFile** (*handle to a file opened for writing or appending; optional; default None*)
If handle is not ``None`` the content is written to this file, otherwise not.
**bToConsole** (*bool; optional; default: True*)
If ``True`` the content is written to console, otherwise not.
**nIndent** (*int; optional; default: 0*)
Sets the number of additional blanks at the beginning of every line of output (indentation).
**sPrefix** (*str; optional; default: None*)
Sets a prefix string that is added at the beginning of every line of output.
**bHexFormat** (*bool; optional; default: False*)
If ``True`` the output is printed in hexadecimal format (but strings only).
**Returns:**
**listOutLines** (*list*)
List of lines containing the prepared output
|
"""
oTypePrint = CTypePrint()
listOutLines = oTypePrint.TypePrint(oData, bHexFormat)
listReturned = []
for sLine in listOutLines:
# if requested add indentation and prefix
sLineOut = ""
if sPrefix is not None:
sLineOut = nIndent*" " + sPrefix + " " + sLine
else:
sLineOut = nIndent*" " + sLine
listReturned.append(sLineOut)
if hOutputFile is not None:
hOutputFile.write(sLineOut + "\n")
if bToConsole is True:
print(sLineOut)
return listReturned
# eof def PrettyPrint(oData=None, hOutputFile=None, bToConsole=True, nIndent=0, sPrefix=None, bHexFormat=False):
# --------------------------------------------------------------------------------------------------------------
# TM***
[docs]class CTypePrint():
def __init__(self):
self.listGlobalPrefixes = []
self.listOutLines = []
def __del__(self):
pass
def _ToHex(self, sString=None):
if ( (sString is None) or (sString == "") ):
return sString
listHex = []
for sChar in sString:
listHex.append(hex(ord(sChar)))
sStringHex = " ".join(listHex)
return sStringHex
[docs] def TypePrint(self, oData=None, bHexFormat=False):
if oData is None:
sLocalPrefix = "[NONE]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : " + str(oData)
self.listOutLines.append(sOut.strip())
elif type(oData) == int:
sLocalPrefix = "[INT]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : " + str(oData)
self.listOutLines.append(sOut.strip())
elif type(oData) == float:
sLocalPrefix = "[FLOAT]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : " + str(oData)
self.listOutLines.append(sOut.strip())
elif type(oData) == bool:
sLocalPrefix = "[BOOL]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : " + str(oData)
self.listOutLines.append(sOut.strip())
elif type(oData) == str:
sLocalPrefix = "[STR]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sData = str(oData)
if bHexFormat is True:
sData = self._ToHex(sData)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : '" + sData + "'"
self.listOutLines.append(sOut.strip())
elif type(oData) == list:
nNrOfElements = len(oData)
if nNrOfElements == 0:
# -- indicate empty list
sLocalPrefix = "[LIST]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : []"
self.listOutLines.append(sOut.strip())
else:
# -- list elements of list
self.listGlobalPrefixes.append("[LIST]")
nCnt = 0
for oElement in oData:
nCnt = nCnt + 1
sCnt = "(" + str(nNrOfElements) + "/" + str(nCnt) + ") >"
self.listGlobalPrefixes.append(sCnt)
self.TypePrint(oElement, bHexFormat) # >>>> recursion
del self.listGlobalPrefixes[-1] # remove prefix count
del self.listGlobalPrefixes[-1] # remove prefix name
elif type(oData) == tuple:
nNrOfElements = len(oData)
if nNrOfElements == 0:
# -- indicate empty tuple
sLocalPrefix = "[TUPLE]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : ()"
self.listOutLines.append(sOut.strip())
else:
# -- list elements of tuple
self.listGlobalPrefixes.append("[TUPLE]")
nCnt = 0
for oElement in oData:
nCnt = nCnt + 1
sCnt = "(" + str(nNrOfElements) + "/" + str(nCnt) + ") >"
self.listGlobalPrefixes.append(sCnt)
self.TypePrint(oElement, bHexFormat) # >>>> recursion
del self.listGlobalPrefixes[-1] # remove prefix count
del self.listGlobalPrefixes[-1] # remove prefix name
elif type(oData) == set:
nNrOfElements = len(oData)
if nNrOfElements == 0:
# -- indicate empty set
sLocalPrefix = "[SET]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : ()"
self.listOutLines.append(sOut.strip())
else:
# -- list elements of set
self.listGlobalPrefixes.append("[SET]")
nCnt = 0
for oElement in oData:
nCnt = nCnt + 1
sCnt = "(" + str(nNrOfElements) + "/" + str(nCnt) + ") >"
self.listGlobalPrefixes.append(sCnt)
self.TypePrint(oElement, bHexFormat) # >>>> recursion
del self.listGlobalPrefixes[-1] # remove prefix count
del self.listGlobalPrefixes[-1] # remove prefix name
elif type(oData) == dict:
nNrOfElements = len(oData)
if nNrOfElements == 0:
# -- indicate empty dictionary
sLocalPrefix = "[DICT]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : {}"
self.listOutLines.append(sOut.strip())
else:
# -- list elements of dictionary
self.listGlobalPrefixes.append("[DICT]")
nCnt = 0
listKeys = list(oData.keys())
for sKey in listKeys:
nCnt = nCnt + 1
oValue = oData[sKey]
sCntAndKey = "(" + str(nNrOfElements) + "/" + str(nCnt) + ") > {" + str(sKey) + "}"
self.listGlobalPrefixes.append(sCntAndKey)
self.TypePrint(oValue, bHexFormat) # >>>> recursion
del self.listGlobalPrefixes[-1] # remove prefix count
del self.listGlobalPrefixes[-1] # remove prefix name
# elif type(oData) == dotdict:
elif ( (type(oData) == dotdict) or (str(type(oData)) == "<class 'robot.utils.dotdict.DotDict'>") ):
nNrOfElements = len(oData)
if nNrOfElements == 0:
# -- indicate empty dot dictionary
sLocalPrefix = "[DOTDICT]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : {}"
self.listOutLines.append(sOut.strip())
else:
# -- list elements of dot dictionary
self.listGlobalPrefixes.append("[DOTDICT]")
nCnt = 0
listKeys = list(oData.keys())
for sKey in listKeys:
nCnt = nCnt + 1
oValue = oData[sKey]
sCntAndKey = "(" + str(nNrOfElements) + "/" + str(nCnt) + ") > {" + str(sKey) + "}"
self.listGlobalPrefixes.append(sCntAndKey)
self.TypePrint(oValue, bHexFormat) # >>>> recursion
del self.listGlobalPrefixes[-1] # remove prefix count
del self.listGlobalPrefixes[-1] # remove prefix name
else:
sLocalPrefix = "[" + str(type(oData)) + "]"
sGlobalPrefix = " ".join(self.listGlobalPrefixes)
sData = str(oData)
if bHexFormat is True:
sData = self._ToHex(sData)
sOut = sGlobalPrefix + " " + sLocalPrefix + " : '" + sData + "'"
self.listOutLines.append(sOut.strip())
return self.listOutLines
# eof def TypePrint(...):
# eof class CTypePrint():
# **************************************************************************************************************