Disclaimer: this is not about pip (in particular)
Hi!
I'm Dana
It's the year 2019
are we supposed to write our own code now??
NOPE.
BUT DOUBT. EVERYTHING.
The good
- Multitude of libraries
- Ease of use
- Open source software
The bad
- Poorly written & documented
- Not optimized
- Might go missing
The ugly
- Security issues
- Malicious activity (typosquatting happening)
- Dependency hell
Review time!
Is the library...
mature?
used in commercial products?
backed up by other organizations?
Is the library...
used all through your project?
heavily relying on other libraries?
Improve the library
Contribute to open source!
Use a pattern...
wrap it up! (the code, that is)
from external_dependency import something
class SomeExternalDependencyClient:
def __init__(self, credentials, name):
self.client = something.Client(credentials, name)
def get_items(self, ids):
self.client.get(ids)
def send_items(self, item_list):
self.client.batch_insert(item_list)
The standard library is awesome!
Good resources
import hashlib
class Hasher(object):
def __init__(self, algorithm):
self.algorithm = algorithm
def __call__(self, file):
hash = self.algorithm()
with open(file, 'rb') as f:
for chunk in iter(lambda: f.read(4096), ''):
hash.update(chunk)
return hash.hexdigest()
md5 = Hasher(hashlib.md5)
sha1 = Hasher(hashlib.sha1)
md5(somefile)
from functools import wraps
def retry(count=5, exc_type=Exception):
def decorator(func):
@wraps(func)
def result(*args, **kwargs):
last_exc = None
for _ in range(count):
try:
return func(*args, **kwargs)
except exc_type as e:
last_exc = e
raise last_exc
return result
return decorator
@retry
def might_fail():
# some code here
class Cache:
def __init__(self):
self.memo = {}
def store(self, fn):
def wrapper(*args):
if args not in self.memo:
self.memo[args] = fn(*args)
return self.memo[args]
return wrapper
def clear(self):
self.memo.clear()
cache = Cache()
@cache.store
def somefct():
return expensive_call()
cache.clear()
or, as of Python 3.4, use the built-in @lru_cache
>>> from collections import Counter
>>> colors = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> counter = Counter(colors)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
>>> counter.most_common()[0][0]
'blue'
>>> Point = collections.namedtuple('Point', 'x y')
>>> p = Point(1, y=2)
Point(x=1, y=2)
>>> p.x
1
>>> getattr(p, 'y')
2
>>> p._fields
('x', 'y')
and so many MORE!
os specific operations
I still think libraries are cool, okay?