Colors in Reportlab

Looking for an exhaustive list of the colors in ReportLab, I was surprised that there wasn’t a list of them — with examples — in the ReportLab docs. Then, when I didn’t quickly find one with Google, I thought I would turn this into a test of my coding chops.

So, this might seem simple to you, but I needed quite a few tries to get it going. Which means, of course, that I’m pretty proud of it.

Here’s the code I wrote:

from reportlab.lib.pagesizes import A4
from reportlab.lib.enums import TA_LEFT
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.colors import getAllNamedColors

doc = []
document = SimpleDocTemplate('colors.pdf', pagesize = A4, rightMargin = 72, leftMargin = 72, topMargin = 72,
                                     bottomMargin = 34)
styles = getSampleStyleSheet()

for color in getAllNamedColors():
    styles.add(ParagraphStyle(name=color, alignment=TA_LEFT, fontSize=12, leading=22, fontName='Helvetica',
    doc.append(Paragraph('Test color '+color, styles[color]))

And here is the result of the code: colors.pdf

The power of integration

So, this is nominally a podcast recommendation for a recent episode of This American Life, called “The problem we all live with.” And, it’s a great episode of a great podcast. Even more, it touches on something I think often about: why we sometimes don’t do the right thing, even though the data are in front of us.

However, the real reason I’m sharing is that a recent discussion of Black Lives Matter got derailed into a discussion of whether or not systemic racism even exists. (To be fair, the phrase white privilege was thrown about a bit, but I don’t think it’s a good one.) And, if I have to say it, I’m coming down on the side of systemic racism does exist and, no, cops shouldn’t kill black people with impunity.

This podcast is great, though, because I think it demonstrates that the system is not so much “built to favor white people” as a lot of people in the discussion suggested, but that there are a lot of things coming together from overt racism, to a fear of ‘urban kids’ and the crime we’re sure they’ll bring with them, to the inequity of how education is funded in the U.S.

When I think of systemic racism, it’s stories like this one — as well as the innumerable black bodies laying in streets — that I think of. Give it a listen.

Revisiting Tomato Paste

So, if anybody is curious about the results of the infamous tomato paste experiment, I’m declaring it a success. As a really quick recap, I spent the summer grossing out friends and family by eating a table spoon of tomato paste every day in the hopes that it would let me avoid using sunblock.

Of course, I have no way to objectively measure the degree of my exposure to the sun, but it was a sunny summer, both in the U.S. where I spent the hottest four weeks, and here in Germany. And, in that time, I never used sunblock. To be fair, I didn’t try to maximize my sun exposure (it was hot!) except in some early mornings, late evenings. But, neither did I ever say “I can’t go out, I’m not wearing sunblock.”

So, there is bad news for my kids. Next summer they’re stuck eating tomato paste, too. (Though I’m not the only one who decides and when and how much sunblock they have to wear.)

A quick and dirty grammar check in NLTK

So, while working on my app to generate worksheets (update: I’m using it! Like, in practice!) I’ve wanted a way to identify the grammar in a sentence. A quick Google search on doing this in NLTK came up mostly with diagramming sentences and looked more complicated than I am ready to tackle. (Though I will learn!)

So, with a bit of poking around, I found a method that I liked. It works with NLTK’s pos_tag function. And that, in turn, works like this:

>>> import nltk
>>> t = "This is a test."
>>> tokens = nltk.word_tokenize(t)
>>> nltk.pos_tag(tokens)
[('This', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('test', 'NN'), ('.', '.')]

NLTK actually includes a help interface to help with the ‘DT’ and ‘VBZ’ tags. It didn’t take me long to put together a few ‘patterns’ that basically represented the grammars I was looking for:

self.grammar_lookup = {
            'SIMPLE_PAST': ['VBD', "VBD-did/RB-n't/VB", "VBD-did/VB", "VBD-did/RB-not/VB"],
            'SIMPLE_PRESENT': ['VBZ', 'VBP', "VBP-do/RB-n't/VB", "VBP-do/RB-not/VB", "VBZ-does/RB-n't/VB",
            'SIMPLE_FUTURE': ['MD-will/VB', "MD-wo/RB/VB", "MD-will/RB/VB"],
            'COMPARISON_AS': ["RB-not/RB-as/JJ/IN-as", "RB-n't/RB-as/JJ/IN-as", 'RB-as/JJ/IN-as',
                              "RB-not/RB-as/RB/IN-as", "RB-n't/RB-as/RB/IN-as", 'RB-as/RB/IN-as'],
            'COMPARISON_THAN': ["JJR/IN-than", "RBR/IN-than"]

As an explanatory note, the ones with a hyphen in them represent the part of speech tag and the specific word. I did that because I want to reduce the chance of false positives.

From there, it was a fairly straightforward process to start iterating over sentences and looking for these patterns. I’m not especially proud of the code that does this and I think that any serious coder could do it more elegantly, so I’m not going to post that. Still, I’m proud of myself for finding a solution to my problem that works…

…for now. (As you can see, I’ve only tested it on five grammars. I’ll add more as I need them.)