Proudly ProcrasDonating
Technology ThoughtsProcrasDoCoder Conversation Starter
Welcome to Proudly ProcrasDonating :-)
Subscribe to my RSS feed and
visit ProcrasDonate.com
The ProcrasDoCoder Ring is
- a conversation starter for my startup, ProcrasDonate
- gives the team a warm fuzzy feeling while we’re working
- a fun introduction to microcontrollers
The ring, or possibly a pin next to one’s name tag or attached to one’s hat, consists of a bright BlinkM RGB LED with long wires to an arduino unit hidden in one’s pocket or belt loop. The LED lights up colorfully and brilliantly for a few seconds whenever a user of ProcrasDonate donates to a charity, makes a pledge, downloads our software or participates in some user test.
Currently, the code to do all this has been written, but the hardware housing is still in prototype phase. I’ll update the following videos and pictures soon; hopefully with a real use case in the wild.
This video shows a simple demo of the WiShield and BlinkM.
How it works
The ProcrasDoCoderRing is a simple mashup that stands on the shoulders of 4 giants:
Arduino + WiShield + BlinkM + ProcrasDonate web server
In case it’s not clear: much of the WiShield and BlinkM code is copied from relevant examples.
- Arduino – Arduino starter pack from AdaFruit, snap.
- WiShield – from AsyncLabs
Nice library. Needed to hack a few config lines in the C code for WEP 5 byte passcode (see section below), but otherwise comes with good documentation.
- BlinkM – RGB LED kit from ThingM
Comes with a nice arduino library that abstracts fading the LED to a specific RGB or HSB.
- ProcrasDonate web server - python Django website
There are two different ways this could work:
- The arduino registers itself with the ProcrasDonate site, which then pushes information to the arduino using HTTP web requests to the WiShield webpage server.
- Instead, the arduino regularly pings a small Django app running on ProcrasDonate. The app has a single webpage, which returns the donation counts, etc.
To view the code and more detailed documentation, see the ProcrasDoCoder github repository.
Proudly ProcrasDonating,
Lucy.
RescueTime integration test: donations as time management incentive
Today I broke from solidifying and bug-fixing the ProcrasDonate Firefox extension in order to test donations as a time management incentive.
I created a small app that uses RescueTime’s API to retrieve a user’s RescueTime time tracking data.
The user authorizes ProcrasDonate to donate to their selected charity at the indicated $/hr rate for all hours spent on activities with a negative RescueTime productivity score.
Keep in mind: this is a barebones minimal test app. Try it out and tell us what you think.
Proudly ProcrasDonating,
Lucy.
Django Tricks, Part 7 – Django from shell
This post is the seventh and last in a series on Django tricks that began with automating Admin Model creation.
This is one of my favorite tricks: setup the Django environment from the Python interpreter.
(master) $ python >>> from lib.django_from_shell import start_django as sd >>> sd() >>> from procrasdonate.models import User >>> User.objects.count() 22
All we need to do is wrap a few Django calls like so:
def start_django(): import sys #Now the nearest ancestor directory with a 'settings.py' file settings_dir = find_file_in_ancestors("settings.py") sys.path.append(settings_dir) from django.core.management import setup_environ import settings setup_environ(settings)
By being flexible about finding the global settings.py file, we can call start_django from other scripts buried in bin or cron directories:
def find_file_in_ancestors(filename): """ For each parent directory, check if 'filename' exists. If found, return the path; otherwise raise RuntimeError. """ import os path = os.path.realpath(os.path.curdir) while not filename in os.listdir(path): #if filename in os.listdir(path): # return path newpath = os.path.split(path)[0] if path == newpath: raise RuntimeError("No file '%s' found in ancestor directories." % filename) path = newpath return path
Conclusion
The goal of these tricks is to reduce copy/past/alter drudgery. It’s rewarding to automate the creation of fluff code, even easy fluff that knocked my socks off when I first learned Django.
Of course, it’s hard to stay impressed with myself or Dan for long since I quickly forget that the fluff code even existed. I suppose that’s part of the point. I can forget about creating Admin Models, and new models still show up in the Admin app as I thoughtlessly expected.
Still, even if I’m not impressed, I do notice how often I get to write new, interesting code. That’s why I’m Proudly ProcrasDonating,
Lucy.
Django Tricks, Part 6 – View Utilities
This post is the sixth in a series on Django tricks.
We started with automating Admin Model creation, and continued with automating initialization and installation, model mixins, forms and app settings.
This post diverges from automation to point out some useful view utilities.
Render Response
This trick is more like standard Django practice: wrap render_to_response with your own function that uses your own RequestContext.
def render_response(request, template, dictionary=None): """ Return render_to_response with context_instance=RequestContext(request). """ dictionary = dictionary or {} return render_to_response(template, dictionary, context_instance=RequestContext(request)) def render_string(request, template, dictionary=None): dictionary = dictionary or {} return render_to_string(template, dictionary, context_instance=RequestContext(request))
One small thing sometimes forgotten is that when you call render_response from your view, you don’t have to write out the dictionary, which is really just a copy/double-paste of local variable names. Instead, call locals().
some_view.py
def info(request): user_count = User.objects.count() visitor_count = Visitor.objects.count() pledge_count = ... donation_count = RecipientPayment.objects.count() return render_response(request, 'procrasdocoder/info.html', locals())
Extract Parameters
Another useful convenience function is extract_parameters, which extracts expected and optional parameters from a request’s POST and GET objects, as well as reporting appropriate errors.
Here’s an example use:
def receive_data(request): expected_parameters = ["private_key", "prefs"] optional_parameters = ["foo", "bar"] response = extract_parameters(request, "POST", expected_parameters) if not response['success']: Log.Error(response['reason'], "communication_error") return json_failure(message) parameters = response['parameters'] private_key = parameters['private_key'] ...
Here is the definition for extract_parameters:
def extract_parameters(request, method_type, expected_parameters, optional_parameters=None): ret = {} if not getattr(request, method_type): return {'success': False, 'reason': "Expected %s parameters" % method_type} for p in expected_parameters: try: v = getattr(request, method_type).get(p, None) if v == None: return {'success': False, 'reason': "Missing expected parameter: %s" % p} ret[p] = v except: return {'success': False, 'reason': "Something unexpected happened while extracting parameters"} optional_parameters = optional_parameters or {} for p in optional_parameters: try: v = getattr(request, method_type).get(p, None) if v: ret[p] = v except: return {'success': False, 'reason': "Something unexpected happened while extracting optional parameters"} return {'success': True, 'parameters': ret}
This is a marathon super-bowl blogging experience for me, and the English to Code ratio is quickly approaching zero. I’ve left the best for last, though, so check it out: Part 7 – Django from shell.
Proudly ProcrasDonating,
Lucy.








