misc module

This module contains miscellaneous utility functions that can be applied in a variety of circumstances; there are context managers, membership functions (test if an argument is of a given type), numerical functions and string functions

Context managers

putil.misc.ignored(*exceptions)

Executes commands and selectively ignores exceptions (Inspired by “Transforming Code into Beautiful, Idiomatic Python” talk at PyCon US 2013 by Raymond Hettinger)

Parameters:exceptions (Exception object, i.e. RuntimeError, OSError, etc.) – Exception type(s) to ignore

For example:

# misc_example_1.py
from __future__ import print_function
import os, putil.misc

def ignored_example():
    fname = 'somefile.tmp'
    open(fname, 'w').close()
    print('File {0} exists? {1}'.format(
        fname, os.path.isfile(fname)
    ))
    with putil.misc.ignored(OSError):
        os.remove(fname)
    print('File {0} exists? {1}'.format(
        fname, os.path.isfile(fname)
    ))
    with putil.misc.ignored(OSError):
        os.remove(fname)
    print('No exception trying to remove a file that does not exists')
    try:
        with putil.misc.ignored(RuntimeError):
            os.remove(fname)
    except:
        print('Got an exception')
>>> import docs.support.misc_example_1
>>> docs.support.misc_example_1.ignored_example()
File somefile.tmp exists? True
File somefile.tmp exists? False
No exception trying to remove a file that does not exists
Got an exception
class putil.misc.Timer(verbose=False)

Bases: object

Profiles blocks of code by calculating elapsed time between the context manager entry and exit time points. Inspired by Huy Nguyen’s blog

Parameters:verbose (boolean) – Flag that indicates whether the elapsed time is printed upon exit (True) or not (False)
Returns:putil.misc.Timer
Raises:RuntimeError (Argument `verbose` is not valid)

For example:

# misc_example_2.py
from __future__ import print_function
import putil.misc

def timer(num_tries, fpointer):
    with putil.misc.Timer() as tobj:
        for _ in range(num_tries):
            fpointer()
    print('Time per call: {0} seconds'.format(
        tobj.elapsed_time/(2.0*num_tries)
    ))

def sample_func():
    count = 0
    for num in range(0, count):
        count += num
>>> from docs.support.misc_example_2 import *
>>> timer(100, sample_func) 
Time per call: ... seconds
elapsed_time

Returns elapsed time (in seconds) between context manager entry and exit time points

Return type:float
class putil.misc.TmpFile(fpointer=None)

Bases: object

Creates a temporary file and optionally sets up hooks for a function to write data to it

Parameters:fpointer (function object or None) – Pointer to a function that writes data to file. If the argument is not None the function pointed to receives exactly one argument, a file-like object
Returns:temporary file name
Raises:RuntimeError (Argument `fpointer` is not valid)

Warning

The file name returned uses the forward slash (/) as the path separator regardless of the platform. This avoids problems with escape sequences or mistaken Unicode character encodings (\\user for example). Many functions in the os module of the standard library ( os.path.normpath() and others) can change this path separator to the operating system path separator if needed

For example:

# misc_example_3.py
from __future__ import print_function
import putil.misc

def write_data(file_handle):
    file_handle.write('Hello world!')

def show_tmpfile():
    with putil.misc.TmpFile(write_data) as fname:
        with open(fname, 'r') as fobj:
            lines = fobj.readlines()
    print('\n'.join(lines))
>>> from docs.support.misc_example_3 import *
>>> show_tmpfile()
Hello world!

File

putil.misc.make_dir(fname)

Creates the directory of a fully qualified file name if it does not exist

Parameters:fname (string) – File name

Equivalent to these Bash shell commands:

$ dir=$(dirname ${fname})
$ mkdir -p ${dir}
Parameters:fname (string) – Fully qualified file name
putil.misc.normalize_windows_fname(fname)

Fix potential problems with a Microsoft Windows file name. Superfluous backslashes are removed and unintended escape sequences are converted to their equivalent (presumably correct and intended) representation, for example r'\x07pps' is transformed to r'\\apps'. A file name is considered network shares if the file does not include a drive letter and they start with a double backslash ('\\')

Parameters:fname (string) – File name
Return type:string

Membership

putil.misc.isalpha(obj)

Tests if the argument is a string representing a number

Parameters:obj (any) – Object
Return type:boolean

For example:

>>> import putil.misc
>>> putil.misc.isalpha('1.5')
True
>>> putil.misc.isalpha('1E-20')
True
>>> putil.misc.isalpha('1EA-20')
False
putil.misc.ishex(obj)

Tests if the argument is a string representing a valid hexadecimal digit

Parameters:obj (any) – Object
Return type:boolean
putil.misc.isiterable(obj)

Tests if the argument is an iterable

Parameters:obj (any) – Object
Return type:boolean
putil.misc.isnumber(obj)

Tests if the argument is a number (complex, float or integer)

Parameters:obj (any) – Object
Return type:boolean
putil.misc.isreal(obj)

Tests if the argument is a real number (float or integer)

Parameters:obj (any) – Object
Return type:boolean

Miscellaneous

putil.misc.flatten_list(lobj)

Recursively flattens a list

Parameters:lobj (list) – List to flatten
Return type:list

For example:

>>> import putil.misc
>>> putil.misc.flatten_list([1, [2, 3, [4, 5, 6]], 7])
[1, 2, 3, 4, 5, 6, 7]

Numbers

putil.misc.gcd(vector)

Calculates the greatest common divisor (GCD) of a list of numbers or a Numpy vector of numbers. The computations are carried out with a precision of 1E-12 if the objects are not fractions. When possible it is best to use the fractions data type with the numerator and denominator arguments when computing the GCD of floating point numbers.

Parameters:vector (list of numbers or Numpy vector of numbers) – Vector of numbers
putil.misc.normalize(value, series, offset=0)

Scales a value to the range defined by a series

Parameters:
  • value (number) – Value to normalize
  • series (list) – List of numbers that defines the normalization range
  • offset (number) – Normalization offset, i.e. the returned value will be in the range [offset, 1.0]
Return type:

number

Raises:
  • RuntimeError (Argument `offset` is not valid)
  • RuntimeError (Argument `series` is not valid)
  • RuntimeError (Argument `value` is not valid)
  • ValueError (Argument `offset` has to be in the [0.0, 1.0] range)
  • ValueError (Argument `value` has to be within the bounds of the argument `series`)

For example:

>>> import putil.misc
>>> putil.misc.normalize(15, [10, 20])
0.5
>>> putil.misc.normalize(15, [10, 20], 0.5)
0.75
putil.misc.per(arga, argb, prec=10)

Calculates the percentage difference between two numbers or the element-wise percentage difference between two lists of numbers or Numpy vectors. If any of the numbers in the arguments is zero the value returned is 1E+20

Parameters:
  • arga (float, integer, list of floats or integers, or Numpy vector of floats or integers) – First number, list of numbers or Numpy vector
  • argb (float, integer, list of floats or integers, or Numpy vector of floats or integers) – Second number, list of numbers or or Numpy vector
  • prec (integer) – Maximum length of the fractional part of the result
Return type:

Float, list of floats or Numpy vector, depending on the arguments type

Raises:
  • RuntimeError (Argument `arga` is not valid)
  • RuntimeError (Argument `argb` is not valid)
  • RuntimeError (Argument `prec` is not valid)
  • TypeError (Arguments are not of the same type)
putil.misc.pgcd(numa, numb)

Calculate the greatest common divisor (GCD) of two numbers

Parameters:
  • numa (number) – First number
  • numb (number) – Second number
Return type:

number

For example:

>>> import putil.misc, fractions
>>> putil.misc.pgcd(10, 15)
5
>>> str(putil.misc.pgcd(0.05, 0.02))
'0.01'
>>> str(putil.misc.pgcd(5/3.0, 2/3.0))[:6]
'0.3333'
>>> putil.misc.pgcd(
...     fractions.Fraction(str(5/3.0)),
...     fractions.Fraction(str(2/3.0))
... )
Fraction(1, 3)
>>> putil.misc.pgcd(
...     fractions.Fraction(5, 3),
...     fractions.Fraction(2, 3)
... )
Fraction(1, 3)

String

putil.misc.binary_string_to_octal_string(text)

Returns a binary-packed string in octal representation aliasing typical codes to their escape sequences

Parameters:text (string) – Text to convert
Return type:string
Code Alias Description
0 \0 Null character
7 \a Bell / alarm
8 \b Backspace
9 \t Horizontal tab
10 \n Line feed
11 \v Vertical tab
12 \f Form feed
13 \r Carriage return

For example:

>>> import putil.misc, struct, sys
>>> def py23struct(num):
...    if sys.hexversion < 0x03000000:
...        return struct.pack('h', num)
...    else:
...        return struct.pack('h', num).decode('ascii')
>>> nums = range(1, 15)
>>> putil.misc.binary_string_to_octal_string(
...     ''.join([py23struct(num) for num in nums])
... ).replace('o', '')  
'\\1\\0\\2\\0\\3\\0\\4\\0\\5\\0\\6\\0\\a\\0\\b\\0\\t\\0\\...
putil.misc.char_to_decimal(text)

Converts a string to its decimal ASCII representation, with spaces between characters

Parameters:text (string) – Text to convert
Return type:string

For example:

>>> import putil.misc
>>> putil.misc.char_to_decimal('Hello world!')
'72 101 108 108 111 32 119 111 114 108 100 33'
putil.misc.elapsed_time_string(start_time, stop_time)

Returns a formatted string with the elapsed time between two time points. The string includes years (365 days), months (30 days), days (24 hours), hours (60 minutes), minutes (60 seconds) and seconds. If both arguments are equal, the string returned is 'None'; otherwise, the string returned is [YY year[s], [MM month[s], [DD day[s], [HH hour[s], [MM minute[s] [and SS second[s]]]]]]. Any part (year[s], month[s], etc.) is omitted if the value of that part is null/zero

Parameters:
  • start_time (datetime) – Starting time point
  • stop_time (datetime) – Ending time point
Return type:

string

Raises:

RuntimeError (Invalid time delta specification)

For example:

>>> import datetime, putil.misc
>>> start_time = datetime.datetime(2014, 1, 1, 1, 10, 1)
>>> stop_time = datetime.datetime(2015, 1, 3, 1, 10, 3)
>>> putil.misc.elapsed_time_string(start_time, stop_time)
'1 year, 2 days and 2 seconds'
putil.misc.pcolor(text, color, indent=0)

Returns a string that once printed is colorized

Parameters:
  • text (string) – Text to colorize
  • color (string) – Color to use, one of 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white' or 'none' (case insensitive)
  • indent (integer) – Number of spaces to prefix the output with
Return type:

string

Raises:
  • RuntimeError (Argument `color` is not valid)
  • RuntimeError (Argument `indent` is not valid)
  • RuntimeError (Argument `text` is not valid)
  • ValueError (Unknown color [color])
putil.misc.quote_str(obj)

Adds extra quotes to a string. If the argument is not a string it is returned unmodified

Parameters:obj (any) – Object
Return type:Same as argument

For example:

>>> import putil.misc
>>> putil.misc.quote_str(5)
5
>>> putil.misc.quote_str('Hello!')
'"Hello!"'
>>> putil.misc.quote_str('He said "hello!"')
'\'He said "hello!"\''
putil.misc.strframe(obj, extended=False)

Returns a string with a frame record (typically an item in a list generated by inspect.stack()) pretty printed

Parameters:
  • obj (tuple) – Frame record
  • extended (boolean) – Flag that indicates whether contents of the frame object are printed (True) or not (False)
Return type:

string