Monday, November 27, 2017
My first real open source project!
Okay, I might be overselling it there in the title. But I have created an open source project, that has a real, publicly available web app and has even had a contribution (some spelling corrections) from another human being. It's a small victory, but I'll take it!
Wednesday, October 25, 2017
Today in things I didn't know about Python - __call__
If you define a __call__ method in your class it will get called when you call an instance of that class. I didn't know that. That is all.
In [336]: class foo:
def __init__(self):
print "in init"
def __call__(self):
print "in call"
In [337]: bar = foo()
in init
In [338]: bar()
in call
In [336]: class foo:
def __init__(self):
print "in init"
def __call__(self):
print "in call"
In [337]: bar = foo()
in init
In [338]: bar()
in call
Monday, May 22, 2017
Today in things I didn't know in Python - sets
I'm slowly and thoroughly reading through the Python documentation. From the amount I'm learning in the process, I clearly should have done this some time ago.
Today I'm reading about sets. I knew a few things about sets:
- Sets are mutable, unordered, collections of unique objects
- You can declare an empty set with 'set()'
- You can declare a set with things in it like this: '{1, 2, 2}'
- You can get the difference, union, intersection, etc. like this:
- my_set.thing_I_want(other_set)
- How to create a set comprehension
But there were things I didn't know about sets:
- You don't have to use the .operation() version, you can use operators! Some of which are more intuitive to me than others.
- There is such a thing as immutable set (it's another class)*
- If you do use the operation_name function version for union, intersection, difference, or symmetric_difference, you don't need to cast the second thing to a set (it just needs to be iterable)
*Edited to add that I've realised it's depreciated and replaced by frozenset since 2.6
Today I'm reading about sets. I knew a few things about sets:
- Sets are mutable, unordered, collections of unique objects
- You can declare an empty set with 'set()'
- You can declare a set with things in it like this: '{1, 2, 2}'
- You can get the difference, union, intersection, etc. like this:
- my_set.thing_I_want(other_set)
- How to create a set comprehension
But there were things I didn't know about sets:
- You don't have to use the .operation() version, you can use operators! Some of which are more intuitive to me than others.
Operation | Equivalent | Result |
---|---|---|
s.issubset(t) | s <= t | test whether every element in s is in t |
s.issuperset(t) | s >= t | test whether every element in t is in s |
s.union(t) | s | t | new set with elements from both s and t |
s.intersection(t) | s & t | new set with elements common to s and t |
s.difference(t) | s - t | new set with elements in s but not in t |
s.symmetric_difference(t) | s ^ t | new set with elements in either s or t but not both |
s.update(t) | s |= t | return set s with elements added from t |
s.intersection_update(t) | s &= t | return set s keeping only elements also found in t |
s.difference_update(t) | s -= t | return set s after removing elements found in t |
s.symmetric_difference_update(t) | s ^= t | return set s with elements from s or t but not both |
- There is such a thing as immutable set (it's another class)*
- If you do use the operation_name function version for union, intersection, difference, or symmetric_difference, you don't need to cast the second thing to a set (it just needs to be iterable)
*Edited to add that I've realised it's depreciated and replaced by frozenset since 2.6
Monday, April 24, 2017
Can you use a tuple as a dictionary key? Well, that depends.
Today I was asked if you can use a tuple as a dictionary key. I wasn't sure, and looked into it. And the answer seems to be, 'it depends'.
Can you ever use a tuple as a dictionary key? Yes:
In [35]: my_tup = (1, 2)
In [36]: my_dict = {my_tup: 1}
In [37]: my_dict
Out[37]: {(1, 2): 1}
Can you ALWAYS use a tuple as a dictionary key? Nope:
In [38]: my_other_tup = ([1, 2], 2)
In [39]: my_dict = {my_other_tup: 2}
------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input...> in <module>()
----> 1 my_dict = {my_other_tup: 2}
TypeError: unhashable type: 'list'
You can use a tuple as a dictionary key, but only if it's hashable all the way down.
Can you ever use a tuple as a dictionary key? Yes:
In [35]: my_tup = (1, 2)
In [36]: my_dict = {my_tup: 1}
In [37]: my_dict
Out[37]: {(1, 2): 1}
Can you ALWAYS use a tuple as a dictionary key? Nope:
In [38]: my_other_tup = ([1, 2], 2)
In [39]: my_dict = {my_other_tup: 2}
------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input...> in <module>()
----> 1 my_dict = {my_other_tup: 2}
TypeError: unhashable type: 'list'
You can use a tuple as a dictionary key, but only if it's hashable all the way down.
Thursday, March 30, 2017
Don't put nullable fields in your MySQL unique keys
MySQL will allow you to include a nullable field in a unique key. I heartilly recommend that you don't do it.
You may already be aware that NULL isn't equal to anything. That's why we always have 'IS NULL' instead of '= NULL' in our where clauses. When they say not equal to anything, they really mean not equal to anything. Not even itself.
So let's say you have a table that looks a bit like this:
and you have a unique key on always2, always3, and sometimes1
You build some logic around the fairly reasonable idea 'we'll try to insert, and if we get a duplicate key error, we'll update instead'.
And then you try to insert
'always2 = "value1", always3 = "value2", sometimes1 = NULL, always1 = m, sometimes2 = n'
expecting this to fail because of a duplicate key error and update the values for always1 and sometimes2 for the third row above. But it won't. Because NULL isn't equal to itself. So you'll end up with a table like this:
Beware!
You may already be aware that NULL isn't equal to anything. That's why we always have 'IS NULL' instead of '= NULL' in our where clauses. When they say not equal to anything, they really mean not equal to anything. Not even itself.
So let's say you have a table that looks a bit like this:
always1 | always2 | always3 | sometimes1 | sometimes2 |
---|---|---|---|---|
a | b | c | d | e |
f | g | h | NULL | NULL |
i | value1 | value2 | NULL | NULL |
and you have a unique key on always2, always3, and sometimes1
You build some logic around the fairly reasonable idea 'we'll try to insert, and if we get a duplicate key error, we'll update instead'.
And then you try to insert
'always2 = "value1", always3 = "value2", sometimes1 = NULL, always1 = m, sometimes2 = n'
expecting this to fail because of a duplicate key error and update the values for always1 and sometimes2 for the third row above. But it won't. Because NULL isn't equal to itself. So you'll end up with a table like this:
always1 | always2 | always3 | sometimes1 | sometimes2 |
---|---|---|---|---|
a | b | c | d | e |
f | g | h | NULL | NULL |
i | value1 | value2 | NULL | NULL |
m | value1 | value2 | NULL | n |
Beware!
Subscribe to:
Posts (Atom)