Day 3: Everybody reads Unicode

Roo Harrigan
Making Athena
Published in
4 min readOct 29, 2015

>>> Brief summary:

Day 3 began much like Day 2: a mentor meeting, a breakfast of champions, and a few much-needed high-fives from Rod Begbie. Then it was off to Hackbright to learn about postgreSQL (from one of its writers, no less) and subsequently put the simplest version of my data modeling into action.

We discussed at length the pros of using SQLite (which is the database Hackbright teaches). I simply cannot fathom how it was written by just one person. One brilliant person.

However, I wanted to take this opportunity to learn another new thing and practice with it throughout the project instead of doing migration at the end if I want to deploy to Heroku. So I spent the better part of the day getting postgreSQL up and running, creating two very basic tables, writing out a seed.py, and trying to re-write my two flask routes to work with the database.

>>> What I learned:

Unicode is not my monkey right now, but it is in my circus.

When Athena generates the quiz question that asks “What is the capital of {{country}}?” that route in the flask app queries the database to grab the right capital string and display that string in a button. So here is the query I wrote for it:

capital = db.session.query(Country.capital).filter(Country.country_name == country_name).first()

But then my button was appearing like this:

Eek!

“What is that scary u thing?” I thought, nervous. “Is my browser not, like, reading this as Unicode?” And I found myself peering down a deep, dark I18N pit I wanted to run from (though the first few paragraphs of this were enough to convince me that I shouldn’t blithely ignore the subject “like most english-speaking engineers”). So I made myself a calendar alert to read more about Unicode. In December. Priorities.

Turns out, structuring a query with db.session.query() at the beginning and .first() at the end returns a tuple (duh), and I was just passing the button a tuple, which is why I was getting the unicode marker.

But this is a smart tuple; it knows about the object from whence it came. So instead of indexing it, I set capital = capital.capital and was on my merry way.

An integer primary key might serve you better than a seemingly natural string primary key.

When I first conceptualized my table for storing country related information, I thought the country name would work well as a natural key. No two countries have the same name, after all, so they are naturally unique.

How superficial of me.

Once I’d gotten the quiz to grab the right answer for a country’s capital, I began working on making pseudo-randomized wrong answers. And you can’t rely on a single request from a table to be anywhere near random. So I needed to use the random Python library, but there was no Pythonic way I could find to write a query that said “grab three capital strings out of the table, make sure they don’t match the capital string you’ve already got, and randomly grab different strings each time.” Once I changed my primary keys to numbers, this little baby worked well:

number_of_countries = Country.query.count()

wrong_id = randint(1, number_of_countries)

Then I could build a nice, friendly list of random integers, check that they weren’t the ID of my correct answer, and easily loop a query with those IDs to get each capital’s name. Then I returned that list, passed it to my generate_quiz function, unpacked the list into wrong answers, passed those answers to my quiz.html via Jinja, and ka-BLAM!:

And the wrong answers are different each time!

I found this rather bald list of requirements that really helped me cement the concept. Unless your table entries have SSNs or ISBNs, you should probably generate auto-incremented numeric keys.

>>> Thoughtful takeaway:

I talked out loud to my database tables today like they were people I was meeting at a party for the first time. Like they’d been there all along (and in fact, some of the data they represent is very, very old). I tried to figure out how they all knew one another, or if they hadn’t met yet. I said things like “Countries, each of you only knows one Continent, but Continents, you each know loads of Countries, don’t you? And nobody knows anything about Users yet, do they?”

Guess I’ll have to introduce them tomorrow.

--

--