# Blog

## Python: Non-standard use of dot operator

In PHP, there is a special . operator to concatenate strings. Of course, we aren't going to do that in Python; it is sort of weird. Instead of that, let's try to solve a legendary NumPy problem: how to distinguish element-wise array multiplication from matrix-matrix 'row-by-column' multiplication? We already know that the first thing is done like A * B, and the second like A.dot(B), or like weird A @ B construction in Python 3.5 draft. Well, let's see some code:

import inspect

class Matrix(object):

def __getattr__(self, which):
frame = inspect.stack()[1][0] # we assume stack is deeper than 1 here
locals = frame.f_locals
if which in locals:
return 'matvec' # return matrix-matrix multiplication result here
else:
return super(Matrix, self).__getattr__(which)

a = Matrix()
b = Matrix()
print(a.b) # outputs 'matvec'!
print(a.c) # raises AttributeError!


What's going on? An awesome thing about Python is that it gives access to the whole execution stack, including local and global namespaces for each frame. We just take the frame operator . was called from, find an element with the requested name, and 'multiply' our matrix by it. If there is no element with such name, we just return regular attribute.

So, it is just a little smart trick to implement an exotic behavior of dot operator. Enjoy using, if only you are brave enough!

Python is awesome.

## Python: Adding a Method to Both Instances and Classes

Have you ever wondered how to create a method that could be called for both a type object and it's instances? It is unachievable with class/static methods and metaclasses at all. But here is a simple solution.

import new
class mutualmethod(classmethod): # subclassing classmethod!
"""mutualmethod(function) -> method

Convert a function to be a mutual method, i. e. a method that can be
called for both class object and it's instances.

A mutual method receives the class or it's instance as it's first
argument.
"""
def __get__(self, obj, t = None):
if t is None:
# I wonder what should I do in this situation.
raise NotImplementedError
if obj is None:
# creating a method bounded to the type object
return new.instancemethod(self.__func__, t, type(t))
else:
# creating a method bounded to an instance
return new.instancemethod(self.__func__, obj, t)


And here are some usage examples:

class A(object):
@mutualmethod
def myrepr(self):
if isinstance(self, type):
pass # you can handle type objects here
else:
pass # you can handle type instances here
return repr(self)

a = A()
a.myrepr() # '<__main__.A object at 0x666666f>'
A.myrepr() # "<class '__main__.A'>"


And a bit more comprehended example:

class HTMLNode(object):
@mutualmethod
def pseudo_selector(self, which):
if isinstance(self, type):
return '.%s:%s' % (self.__name__, which)
else:
return '#%r:%s' % (id(self), which)

class div(HTMLNode):
pass

my_element = div()
my_element.pseudo_selector('hover') # '#31415926:hover'
div.pseudo_selector('hover')        # '.div:hover'


## 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



## Singletons and Other Unique Objects in Python

A brief depiction of the problem. As I was developing a backend for my Python game, I created a class for game objects which could create them from database records (in my case, MongoDB documents) and embed into the game core. And then I faced the problem of uniqueness of my objects. With many clients connecting to the backend, it is possible that some objects could be requested from database multiple times. But if I had allowed to create multiple objects for same entity, I would have surely encountered problems in my game logic.

I could surely create some dict which could contain references to created objects, but how to do that in a nice way? Here is the solution I've came to.

I have already wrote that  metaclasses are awesome pythonic tool that allows to change completely object creation logic. Python __new__ methods can't do that. Consider the following code:

class A(object):
objects_by_unique_data = {}
def __new__(cls, data):
if data in cls.objects_by_unique_data:
return cls.objects_by_unique_data[data]
else:
result = object.__new__(cls)
cls.objects_by_unique_data[data] = result
return result

def __init__(self, data):
print "Hi there! I'm doing stuff!"

Yeah, you can save some memory using this. But actually __init__ method will run every time you create an object, even if the data is doubled. So what can we do?

Here is the solution using Python metaclasses.

from weakref import WeakValueDictionary

class metaA(type):
def __call__(self, data):
if data in self.objects_by_unique_data:
return self.objects_by_unique_data[data]
else:
result = type.__call__(self, data)
self.objects_by_unique_data[data] = result
return result

class A(object):
__metaclass__ = metaA
objects_by_unique_data = WeakValueDictionary()

#def __new__(...) - not needed!

def __init__(self, data):
print "I am now sure I'm unique. ^__^"


So, the call to A(...) itself is redefined! There is no need in __new__ at all now, as all the work is done in type(A).__call__. Also note use of WeakValueDictionary. This dictionary contains auto-deleted weak references to objects, thus your objects will be garbage-collected if you won't need them in your program core. If we used dict, it would keep the strong references forever, disallowing garbage collector to clean up the house.

Python is awesome.