Source code for PythonCK.stringutils

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""

Utilities related to string

"""

from six.moves import zip_longest  # itertools
import re

#===============================================================================

[docs]def concat_multilines(*msgs): r""" Concat horizontally list of multi-line strings. Useful for printing long-thin paragraph together. Args: msgs (list of str): list of paragraphs. Usage:: >>> print(concat_multilines('line11\nline12', 'line21\nline22')) line11 line21 line12 line22 """ widths = [max(len(line) for line in msg.split('\n')) for msg in msgs] tmp = (('{:%i} '*len(widths))%tuple(widths)).strip() gen = zip_longest(*[msg.split('\n') for msg in msgs], fillvalue='') return '\n'.join([tmp.format(*words) for words in gen]).strip()
#===============================================================================
[docs]def insert_line(msg, index, line): r""" Similar to list.insert, for inserting line into a paragraph. >>> print(insert_line('line1\nline2\nline3', 1, 'xxx')) line1 xxx line2 line3 """ l = msg.split('\n') l.insert(index, line) return '\n'.join(l)
#===============================================================================
[docs]def lreplace(string, pattern, sub): """ Replaces 'pattern' in 'string' with 'sub' if 'pattern' STARTS WITH 'string'. It's actually better if I remember this regex by heart. >>> lreplace('prefix_word', 'prefix_', 'new_') 'new_word' """ return re.sub('^%s' % pattern, sub, string)
#=============================================================================== def _remove_vertical_duplicate(paragraph, tag): """ Given a paragraph, remove the duplicate substring if it's directly below the first occurence. Useful for showing the multiindex in markdown. """ n = len(tag) newtag = [' ']*n lines = paragraph.split('\n') for i, line in enumerate(lines): if tag in line: idx = line.index(tag) ## seek the next lines for replacement, only for consecutive lines for j, line2 in enumerate(lines[i+1:]): if line2[idx:idx+n] == tag: # replace l = list(line2) l[idx:idx+n] = newtag lines[i+1+j] = ''.join(l) else: break return '\n'.join(lines)
[docs]def remove_vertical_duplicate(paragraph, *tags): r""" Generic extension where arbitary amount of tags can be used to remove. >>> print(remove_vertical_duplicate( ... "muon PT\n" ... "muon Eta\n" ... "muon Phi\n" ... "tau PT\n" ... "tau Eta\n" ... "tau Phi" ... , 'muon ', 'tau ')) muon PT Eta Phi tau PT Eta Phi """ for tag in tags: paragraph = _remove_vertical_duplicate(paragraph, tag) return paragraph
#===============================================================================
[docs]def try_int_else_float(s): """ Given the string of number, return the float of that number, and cast to int if possible. Raise exception otherwise >>> try_int_else_float('2.00') 2 >>> try_int_else_float('2.50') 2.5 Note: python2,3 has slightly different error msg for below.:: >>> try_int_else_float('not_a_number') Traceback (most recent call last): ... ValueError: could not convert string to float: ... """ x = float(s) return int(x) if x.is_integer() else x
#===============================================================================