I love this
post by Austin Kleon.
As someone who has found very few things that I don’t find intriguing in some
way, it is nice to know that there are others like me and that maybe there’s
nothing wrong with that. I love being a doctor and I love being a programmer,
and I love honing both of those crafts.
He also links to a
2012 New York Times article about a UCLA sophomore
who spends 1 hour each day learning something new, mainly by taking online
courses from other universities or watching how-to videos on YouTube. We live in
a golden age, don’t we? I mean, sure, people will look back at our period of
history and cringe quite a bit, but the idea that I can search just about any
term, and find information about it on Wikipedia, and probably find a course on
it by an actual college professor…. it’s just mind boggling. I’m lucky as it
is, but I often think about if I was a kid growing up in this era. I’d be
overwhelmed, sure, but I would totally be taking online courses left and right.
Actually, even if I weren’t a kid. I just googled the subject of that NYT
article and found his twitter account. His
most recent post
is from 2016 but links to a YouTube series from UCLA on the history of India. I
am TOTALLY watching that.
Let’s play ‘Spot the bug’. We’re building a simple system that shows photos. Each photo has a
publish_date
and we should only show photos that have been published (i.e. their publish_date
is
in the past).
class PhotoManager(models.Manager):
def live(self, as_of=None):
if as_of is None:
as_of = timezone.now()
return super().get_query_set().filter(publish_date__lte=as_of)
And the view to show those photos:
class ShowPhotosView(ListView):
queryset = Hero.objects.live()
Can you spot the bug? I sure didn’t… until the client complained that newly published photos never
showed up on the site. Restarting the server fixed the problem temporarily. The newly published
photos would show up, but then any photos published after the server restart again failed to
display.
The problem is that the ShowPhotosView
class is instantiated when the server starts.
ShowPhotosView.queryset
gets set to the value returned by Hero.objects.live()
. That, in turn, is a
QuerySet
, but it’s a QuerySet
with as_of
set to timezone.now()
WHEN THE SERVER STARTS UP. That
as_of
value never gets updated, so newer photos never get captured in the query.
There’s probably multiple ways to fix this, but an easy one is:
class ShowPhotosView(ListView):
def get_queryset(self):
return Hero.objects.live()
Now, instead of the queryset being instantiated at server start-up, it’s instantiated only when
ShowPhotosView.get_queryset()
is called, which is when a request is made.
A few cool Emacs posts have flown across my radar, so I’m noting them here for that time in the
future when I have time to play with them.
I wrote my first blog post in a little while (ok, ok… 18 months) yesterday and when I tried to
generate the post, it failed. Silently failed, which is the worst kind of failure. I’m still not
sure why it was silent, but I eventually was able to force it to show me an error message:
/home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/pygments.rb-0.3.4/lib/pygments/popen.rb:354:in `rescue in get_header': Failed to get header. (MentosError)
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/pygments.rb-0.3.4/lib/pygments/popen.rb:335:in `get_header'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/pygments.rb-0.3.4/lib/pygments/popen.rb:232:in `block in mentos'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/1.9.1/timeout.rb:68:in `timeout'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/pygments.rb-0.3.4/lib/pygments/popen.rb:206:in `mentos'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/pygments.rb-0.3.4/lib/pygments/popen.rb:189:in `highlight'
from /home/vinod/dev/kurup.org/plugins/pygments_code.rb:24:in `pygments'
from /home/vinod/dev/kurup.org/plugins/pygments_code.rb:14:in `highlight'
from /home/vinod/dev/kurup.org/plugins/backtick_code_block.rb:37:in `block in render_code_block'
from /home/vinod/dev/kurup.org/plugins/backtick_code_block.rb:13:in `gsub'
from /home/vinod/dev/kurup.org/plugins/backtick_code_block.rb:13:in `render_code_block'
from /home/vinod/dev/kurup.org/plugins/octopress_filters.rb:12:in `pre_filter'
from /home/vinod/dev/kurup.org/plugins/octopress_filters.rb:28:in `pre_render'
from /home/vinod/dev/kurup.org/plugins/post_filters.rb:112:in `block in pre_render'
from /home/vinod/dev/kurup.org/plugins/post_filters.rb:111:in `each'
from /home/vinod/dev/kurup.org/plugins/post_filters.rb:111:in `pre_render'
from /home/vinod/dev/kurup.org/plugins/post_filters.rb:166:in `do_layout'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/post.rb:195:in `render'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:200:in `block in render'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:199:in `each'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:199:in `render'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/lib/jekyll/site.rb:41:in `process'
from /home/vinod/.rbenv/versions/1.9.3-p286/lib/ruby/gems/1.9.1/gems/jekyll-0.12.0/bin/jekyll:264:in `<top (required)>'
from /home/vinod/.rbenv/versions/1.9.3-p286/bin/jekyll:23:in `load'
from /home/vinod/.rbenv/versions/1.9.3-p286/bin/jekyll:23:in `<main>'
Professor Google tells me that this happens when you try to
run the pygments.rb library in a Python 3 environment.
(pygments.rb is a Ruby wrapper around the Python Pygments library). The fix is to run the code in a
Python2 virtualenv. I guess the last time I updated my blog, Arch still had Python2 as the system
default. No, I don’t want to check how long ago that was.
$ mkvirtualenv -p `which python2` my_blog
(my_blog)$ bundle exec rake generate
So now I’m running a Ruby command in a Ruby environment (rbenv) inside a Python 2 virtualenv. Maybe
it’s time to switch blog tools again…
It’s occasionally useful to be able to create a Django model class in your unit test suite. Let’s
say you’re building a library which creates an
abstract model
which your users will want to subclass. There’s no need for your library to subclass it, but your
library should still test that you can create a subclass and test out its features. If you create
that model in your models.py
file, then Django will think that it is a real part of your library and
load it whenever you (or your users) call syncdb
. That’s bad.
The solution is to create it in a tests.py
file within your Django app. If it’s not in models.py
, Django won’t load it during syncdb
.
from django.db import models
from django.test import TestCase
from .models import MyAbstractModel
class MyTestModel(MyAbstractModel):
name = models.CharField(max_length=20)
class AbstractTest(TestCase):
def test_my_test_model(self):
self.assertTrue(MyTestModel.objects.create(name='foo'))
A problem with this solution is that I rarely use a single tests.py
file. Instead we use multiple
test files collected in a tests package. If you try to create a model in tests/test_foo.py
, then
this approach fails because Django tries to create the model in an application named tests
, but
there is no such app in INSTALLED_APPS. The solution is to set app_label
to the name of your app
in an inner Meta class.
from django.db import models
from django.test import TestCase
from ..models import MyAbstractModel
class MyTestModel(MyAbstractModel):
name = models.CharField(max_length=20)
class Meta:
app_label = 'myappname'
class AbstractTest(TestCase):
def test_my_test_model(self):
self.assertTrue(MyTestModel.objects.create(name='foo'))
Oh, and I almost forgot… if you use South,
this might not work, unless you set SOUTH_TESTS_MIGRATE
to False
in your settings file.
Comments and corrections welcome!
A Vignette
A 22-month-old previously healthy girl was brought to the emergency
room in respiratory distress. She had been well until the day of
presentation. Shortly after disembarking from an airline flight, she
developed cough with one episode of emesis. En route to the emergency
room, her breathing became labored and she developed hives. She was
diagnosed as having an allergic reaction and treated aggressively with
IV methylprednisolone, IV diphenhydramine, inhaled albuterol, and
oxygen. Mechanical ventilation was not required and her symptoms
improved rapidly. She was monitored in the emergency room for an
extended period and discharged in stable condition with a prescription
for diphenhydramine and methylprednisolone solutions. No specific
allergen was identified. She was seen by a pediatric allergist where
she was found to have a 6 mm response to peanut on skin prick testing,
and a peanut-specific IgE level of 52 kU/L. She was diagnosed as
having severe peanut allergy and avoidance was strongly recommended.
Discussion
Peanut allergy affects between 0.4 and 2.0% of children. Prevalence
has been increasing in recent years, but the reason for this increase
is not well understood. If reactions are identified immediately,
treatment is usually effective. Despite this, about 200 people die
each year from peanut reactions. Biphasic reactions, in which the
initial reaction subsides, but then recurs within a few hours, are
common. The second portion of a biphasic reaction is often less
treatable. Because of this risk, patients should be monitored for at
least 4 hours after a reaction. Patients who successfully treat their
own reactions with subcutaneous epinephrine should still seek medical
attention, again to monitor for biphasic reactions.
The gold standard for diagnosis is a double blind placebo controlled
food challenge (DBPCFC), but this is rarely done. A diagnosis can
usually be reliably made with clinical history, skin prick testing and
a peanut-specific IgE blood test (psIgE). A skin prick test involves
pricking the skin with a needle that is exposed to peanut extract and
measuring the allergic rash that develops. The psIgE blood test
measures the amount of antibody against peanut proteins. The higher it
is, the more allergic the patient is. A positive skin test or psIgE is
not sufficient for the diagnosis. Some type of reaction to peanuts is
required (either spontaneous, or via monitored food challenge).
Peanut allergy was previously felt to be permanent, but recent
evidence documents that 20% of children outgrow their allergy. More
than 60% of patients with an psIgE level of less than 5 passed a food
challenge. IgE levels correlate inversely with likelihood of
resolution, but this correlation is by no means perfect. Some patients
with undetectable psIgE levels will fail a challenge, while some
patients with very high psIgE levels will pass. One expert recommends
waiting until the age of 4 to consider a challenge, and to use a
cutoff psIgE level of less than 5 kU/L in most patients. Recurrence
of peanut allergy after resolution is rare, but is associated with the
lack of regular peanut intake after resolution of the allergy.
Controversy exists regarding risk factors for developing peanut
allergy. The AAP initially recommended that peanut not be introduced
early in a child’s life, but rescinded that advice given the lack of
evidence behind it. This leaves a void for parents as there is no
recommendation to withold or introduce peanuts to toddlers. It is also
not clear if maternal peanut intake during pregnancy or breast feeding
increases the risk of developing peanut allergy in children. Studies
have been conflicting, so more definitive studies are underway. No
evidence-based advice can be given one way or the other to pregnant or
breastfeeding women, but at the minimum, there is no good evidence to
support avoiding peanuts.
The mainstay of treatment is education. Parents should be taught not
only how to identify peanuts in foods, but to identify situations
which are high-risk for exposure to peanuts. Avoidance of buffets,
ice-cream parlors, and bakeries is recommended because the risk of
cross-contamination in those setting is high. Religious reading of
food labels is important. Patients who are allergic to peanuts are
often also allergic to tree nuts, despite the dissimilarity in those
food types. Highly refined peanut oil is usually NOT a risk, but
cold-pressed peanut oil is not safe.
Most importantly, an epi-pen should be carried at all times and extra
doses should be left at daycare facilities and schools. All caregivers
should be comfortable giving an epi-pen injection and this should be
provided at the first sign of a systemic allergic reaction. Waiting to
give diphenhydramine or other therapies a “chance to work” can be
dangerous. Follow a Food Allergy Action Plan
Over 80% of people who died from allergic reactions were not given
appropriate instructions on how to prevent future reactions. Most
mortality occurs because of late treatment. If you take one thing away
from this long post, keep an epi-pen handy and use it liberally.
Trials are underway investigating various oral-based immunotherapies,
but none are strongly recommended at this point. Injection
immunotherapy has not been found to be useful.
So, the 22 month old above is Anika and she gave us the scare of our
life a couple years ago. The scary part now is that we never saw her
actually eat a peanut, so we’re especially vigilant now. Fortunately,
Anika seems to understand the importance of avoiding peanuts. When she
was diagnosed, I did some research but never documented my notes. She
recently had another allergist appointment, so I reviewed those notes
and any new data. I figured I should write up my notes so I wouldn’t
have to review this again from scratch every year. I didn’t intend it
to come out so ‘medical-speaky’, but there it is. Anika and Kavi are
sitting next to me as I write this and they want to give some
information to you, too.
Kavi says:
“Always ask at the restaurant if things have peanuts and make foods
at home that do not have peanuts. Always check if there are peanuts in
every food you eat.”
Anika says:
“We might have to go to the doctor if we eat peanuts. If I eat
peanuts by accident, my teacher will give me a Happy-Pen (epi-pen).”
References
- Sampson HA. Peanut Allergy. N Engl J Med, 2002;346;1294-8.
http://www.nejm.org/doi/full/10.1056/NEJMcp012667
- Fleischer DM, et. al. The natural progression of peanut allergy:
Resolution and the possibility of recurrence. J Allergy Clin
Immunol, 2003;112;183-9.
http://www.jacionline.org/article/S0091-6749(03)01251-X/abstract
- O’B Hourihane J. Peanut Allergy. Pediatr Clin N Am, 2011;58;445-57.
http://www.pediatric.theclinics.com/article/S0031-3955(11)00006-X/abstract
- Rinaldi M, et. al. Peanut allergy diagnoses among children
residing in Olmstead County, Minnesota. J Allergy Clin Immunol, 2012:130:945-50.
- Burks AW. Early peanut consumption: postpone or promote? J Allergy
Clin Immunol. 2009:123:417-423.
http://www.jacionline.org/article/S0091-6749(08)02436-6/fulltext
Here’s a
medline feed URL
that I monitor which should show new studies or reviews related to
this topic.
Pre-GTD task management systems recommended that you assign a priority
to each task. When looking at a list of tasks, you then choose the
ones with the highest priority. David Allen (author of GTD) includes
‘priority’ as one of the things that you should consider when you are
deciding what to do, but only after you have considered context, time
available, and energy available. Which makes sense. As Merlin Mann
says, it doesn’t matter if mowing your lawn is your highest priority
when you’re sitting in an airplane. Only if you’re in the right
context with the right amount of time and the right amount of energy,
should you consider which of the remaining available tasks is highest
priority.
The risk, though, is that there are so many little ‘easy’ tasks that I
could do instead of important, ‘hard’ tasks. I’m also really good at
convincing myself that I don’t have the energy available to do harder
tasks when I really should. So when I get back into GTD, I process all
the things hiding in the back of my brain which leads to the creation
of lots of simple tasks. Google this, buy that, throw away the other
thing. But the two things that I really want to be doing more are
writing and programming. Both of those take blocks of uninterrupted
time and effort, so I end up subconsciously shying away from them. I
actually feel better about it, too, because now I have all these other
tasks that I can do instead. So, I feel productive, even when ignoring
the more important things that I should be doing. I’m moving more
efficiently, but in the wrong direction.
I’ve avoided that a little bit this time by doing a little bit of
prioritization each night before I go to bed. I look through my todo
list and pick about 3-5 things that I want to get done the next day. I
tag those with the ‘today’ tag and then the next morning I look at
that list and start working on those things before doing anything
else. I’ve heard this
trick from a lot of
people before, so I don’t remember who I heard it from first.
So far it’s been effective for me. The problem always starts again
though when I go back on service, because then I can only really focus
on one thing and that is getting my work done at the hospital. We’ll
see if I can somehow figure out a way to get at least one non-work
thing done on each of those days.
Thanks to
Merlin Mann’s recent series of podcasts on GTD,
I’m getting back on the GTD wagon (for about the 100th time). I read
Getting Things Done in 2002 and have been
trying to implement it ever since. I’ve had periods where I followed
it religiously for a month at a time, but it’s never completely stuck.
From what I hear, this is normal and I accept it now. This won’t be
the last time that I restart GTD. Even when I’m not actively using
GTD, I think in GTD terms, thinking about next actions and projects
and ruthlessly placing projects on the backburner. I just have trouble
sticking with the entire GTD workflow, especially the ubiquitous
capture (I trust my brain too much) and the weekly reviews (they just
seem too painful). I’ve used every online and offline tool in the
book, too. Despite not doing so great with GTD, I’d say my life is an
overwhelming success.
So why try again? Each time I have gotten back on the bandwagon, I’ve
had a surge in productivity. I wrote more. I made some clear decisions
on issues that I had been procrastinating on. I wouldn’t be surprised
if each of my major life improvements over the past 10 years was
associated with a time where I got back on the GTD wagon. I can’t
prove that, because I don’t keep enough details, but I always feel
better and think clearer when I’m on GTD.
But, I’ve failed so many times… what kind of hubris makes me think
I’ll get it this time?
“Fall down seven times, get up eight."
Parenthood has taught this to me. Of course we don’t expect our kids
to learn each skill the first time they try. We expect that walking
and reading and writing and bike-riding will take time, multiple
efforts, and multiple failures. But eventually they will get it. Yet,
with each failure, kids get upset (to varying degrees). The answer at
that point is not to tell them to give up. Yet, that’s what I do to
myself. So, I’m going to treat myself like a kid and let myself fail,
understanding that each failure will get me closer to that one time
where I will succeed.
I think twitter and facebook stunt my writing. The more that I read
tweets, the more self-conscious I get when I write. Not that my
writing is all that original, but I still feel that it is something
that comes from me. I worry so much about presenting ideas of others
as my own without even remembering that I had seen the ideas before.
In the old days, the things that I read were long form. Books,
articles, maybe blog posts. They each left an impression on me, maybe
good, maybe bad, but I had a sense where they were coming from. When I
wrote I could reliably say where the inspiration for my idea had come
from. Now with twitter, I see all these ideas and thoughts, some of
which are interesting, but few of which leave a lasting impression on
me. So now I have this fear that the things that I am considering my
own ideas are actually the ideas of others, improperly attributed. Of
course, that’s silly. No idea is original, but it’s just serious
enough to stifle my writing. Because, as a writer, I am the
scaredy-cat of all scaredy-cats and any criticism of my writing bites
deep to the heart. I also know that this is something that I just need
to get over. You cannot express ideas without inviting criticism.
I also don’t just want to let criticism fall off me. I want to learn
from critics. But saying all that doesn’t necessarily make it any
easier. Even writing this post, I feel like a fraud. I’ve said that
I’m a writer a couple times up there, but what evidence do I have to
support that claim? Most of my blog posts are so simple or technical
or repetitive. Nothing that would strike me as an ‘original idea’.
This whole post makes it seem like I am more important or better than
I really am.
What is my point with all this? I want to be able to write. I know
that there are people out there who could benefit from things in my
brain (maybe not a lot). I know that there are people out there who
can help me (in ways that I can’t even expect). So, I want to write
and I want it to be freely flowing and I don’t want to force myself to
feel that what I am writing is useful or authoritative or perfect. I
apologize to you, Vinod, my biggest critic. I know that you are
cringing inside because you’re thinking that anyone who reads this
will think that you are so full of yourself for even considering
yourself a writer. But, this is my first step in letting my guard down
to get this blog flowing. Because I do believe that writing is healthy
and will make me a better person.
In addition to committing to blogging more frequently, I’m also going
to try a twitter hiatus for a week and see what happens.
Now that we have 3 kids, I’m always internally comparing one to the
other. Sure that’s not healthy and will probably breed resentment in
them during their teenage years, but what’s a bad parent to do?
I need an app that takes 2 kids' birthdays and then shows me what day
it was when the older kid was the age that the younger kid is now.
Wow, that’s a confusing sentence. In simpler terms, if I have a
3-year-old and a 1-year-old, then the app would show me the day that
the 3-year-old was 1.
Then, I want the app to take that date and go through all of my
personal files (photos, notes, twitter stream, facebook stream, etc.)
and show me what was happening in our life around that day.
In short, it would show a snapshot of what our life was like when the
older kid was the age that the younger kid is now. I’d call it
WhenIWasYourAge or something catchy like that.
Seems simple enough to build, but I don’t see myself getting to it
anytime soon. Smart people say to set your ideas free and if they love
you they’ll come back. (Wait, I think I’m mixing metaphors here).