## Python Code Snippets

Here I will keep some code that I could add to any of my projects as some utility module.

# Iteration tools

Besides the itertools module itself, there is a big collection of recipes right in the official Python documentation. But I still wish to introduce some utility functions here.

import operator

def split_by_condition(condition, iterable):
"""split_by_condition(function or None, sequence) -> \
pair of lists, tuples, or strings

Split sequence into two subsequences by condition and return them.
"""
if condition is None:
not_condition = operator.not_
else:
not_condition = lambda item: not condition(item)
t = filter(condition, iterable)
f = filter(not_condition, iterable)
return t, f

def filter_element(element, iterable):
"""filter_element(object, iterable) -> list, tuple, or string

Delete all occurrences of object in iterable and return new one."""
# this is surely not a big deal, of course.
# but take a look at this incredibly clear and simple solution:
return filter(element.__ne__, iterable)
# well, it actually doesn't work in 100% of situations because
# sometimes __ne__ raises NotImplementedError.

# Math

from math import copysign, pi, atan2
from numbers import Number
from operator import mul

# sign function. I wonder why there aren't any in Python.
def sign(x):
"""sign(x)

Return integer 1 or -1 depending on the sign of x.
"""
return int(copysign(1, x))

# prod function, brother of sum.
def prod(iterable, start=1):
"""prod(sequence[, start]) -> value

Returns the product of a sequence of elements, beginning with
the value of parameter 'start' (which defaults to 1). When the
sequence is empty, returns start."""
return reduce(mul, iterable, start)
# WARNING: reduce is in itertools module in Python 3

# function finding cardinal direction name.
def cardinal_direction(dx, dy):
"""cardinal_direction(dx, dy)

Returns initials of cardinal direction pointed by (dx, dy).

Usage examples:
>>> cardinal_direction(1, 1)
'NE'
>>> cardinal_direction(-1, 1)
'NW'
"""
angle = atan2(y, x)
angle_idx = int(4. * angle / pi + 8.5) % 8
return ['E','NE','N','NW','W','SW','S','SE'][angle_idx]

# now i'm going to introduce the shortest vector math class possible.
# if you wish to use some vector math but don't want to depend on NumPy -
# this is the solution.
from numbers import Number
import operator

# some accessory decorators first.
def _vectorize(op, name=None, doc=None):
def fn(self, other):
if isinstance(other, Number):
return vector(op(item, other) for item in self)
else:
return vector(map(op, self, other))
fn.__name__ = name or op.__name__
fn.__doc__  = doc
return fn

def _reverse(op):
return lambda *args: op(*args[::-1])

class vector(tuple):
"""The simpliest vector class possible.
Supports basic vector-vector and vector-number
arithmetical operations.
"""
__sub__  = _vectorize(operator.sub, '__sub__')
__mul__  = _vectorize(operator.mul, '__mul__')
__div__  = _vectorize(operator.div, '__div__')
__rsub__ = _vectorize(_reverse(operator.sub), '__rsub__')
__rmul__ = _vectorize(_reverse(operator.mul), '__rmul__')
__rdiv__ = _vectorize(_reverse(operator.div), '__rdiv__')
# add any operations you wish here.

def __abs__(self):
"""Computes euclidian length of a vector."""
return sum(abs(item) ** 2 for item in self) ** 0.5

def transpose(self): # yep, it works on matrices as well
return vector(map(vector, zip(*self)))



# Strings

import re # this is promising

def split_by_capitals(s):
""""split_by_capitals(S) -> string

Return a copy of the string S with all case changes padded with spaces.

>>> split_by_capitals('HiThere')
... 'Hi There'"""
words = re.findall('[A-Z][^A-Z]*', s)
return ' '.join(words)

def decapitalize(s):
"""decapitalize(S) -> string

Return a copy of the string S with its first character
lowercase."""
return s[:1].lower() + s[1:]

def untitle(s):
"""untitle(S) -> string

Return an untitlecased version of S, i. e. words start with lowercase
characters, all remaining cased characters keep their case."""
words = s.split(' ')
words = map(decapitalize, words)
return ' '.join(words)


# Miscellaneous

def superposition(f, g, *args):
"""superposition(callable1, callable2, ...) -> function

Create a function implementing superposition of arguments."""
def result(*args, **kwargs):
return f(g(*args, **kwargs))
result.__name__ = '%s * %s' % (f.__name__, g.__name__)
if args:
result = superposition(result, *args)
return result