4 Useful Python Code Snippets#
Simulate a simple probability outcome#
It’s a really simple function, in fact, it really doesn’t need to be a function except for a little convenience.
from random import uniform
def chance(p):
'''Simulates an event with p probability of being true. This is 0 to 1.
'''
return p >= uniform(0, 1)
An anonymous object (à la Javascript)#
Note
Update: Use a builtin class like types.SimpleNamespace
or collections.namedtuple
instead of this.
In Javascript, OOP is more unconventional than Python (from a C++ and Java perspective).
Part of this is objects can be created with what is similar to dictionary notation in Python: {member: 0, time: "Now"}
.
Also “blank” objects: {}
.
What I have here is a shortcut for creating such objects in Python.
I imagine this might be useful in testing of code that handles many different kinds of objects.
class Anonymous:
def __init__(self, **attrs):
for k, v in attrs.items():
setattr(self, k, v)
def __repr__(self):
return '<{}: {}>'.format(self.__class__.__name__, repr(self.__dict__))
def __str__(self):
return repr(self)
See if a Python iterable is empty#
See if a Python iterable (list
, dict
, any object that implements __iter__
) is empty.
Unfortunately for a generator this means calling next which may change its state.
def has_method(obj, method_name):
'''See if object has a method, should work if its assigned to class or
to the object itself.
'''
return hasattr(obj, method_name) and callable(getattr(obj, method_name))
def is_empty(obj):
'''Determines if a iter object is empty. First checks if its a generator,
then sees if it throws StopIteration the first time. If its not a generator
then it just checks the length.
'''
if not has_method(obj, "__iter__"):
raise TypeError("obj does not have an __iter__ method")
if has_method(obj, "__next__"):
try:
next(obj)
except StopIteration:
return True
return False
else:
return len(obj) == 0
Set default attributes in a Python class#
This one is my favorite, it is a sort of mini version of attrs that I made before hearing about it. It can be used to set default attributes for a class which are overridable from the constructor.
def defaults(obj, kwargs, **defaults):
'''Iterate defaults and keyword arguments, set obj attribute to keys and
their values. Use to set default instance attributes and override them
with keyword arguments at the same time.
'''
for k, v in defaults.items():
if k not in kwargs:
setattr(obj, k, v)
for k, v in kwargs.items():
if k in defaults:
setattr(obj, k, v)
else:
raise ValueError(
'"{}" is not a valid keyword argument to {}'.format(
k,
obj.__class__.__name__
)
)
An Example:#
class SomeClass:
def __init__(self, major_value, **kw):
self.major_value = major_value
defaults(self, kw,
minor_value1 = "Stuff",
minor_value2 = "Stuff Stuff"
)
# ...
>>> someobj = SomeClass(10)
>>> someobj.minor_value1
"Stuff"
>>> someobj.minor_value2
"Stuff Stuff"
>>> anotherobj = SomeClass(11, minor_value2 = "Another Value")
>>> anotherobj.minor_value2
"Another Value"
You can of course remove the error checking after else: raise ValueError...
, because Python is very flexible and you are free to do whatever.