bencrowder.net /blog

#python

Page 1 of 2 (13 posts)

Mozilla just announced their Pyodide project, built with WebAssembly and emscripten:

Pyodide gives you a full, standard Python interpreter that runs entirely in the browser, with full access to the browser’s Web APIs.

WebAssembly has a lot of potential. I’m excited to see where it goes.

Book of Mormon study edition 2.0

I’m pleased to announce version 2.0 of my Book of Mormon study edition.

study-edition-eng-bofm-00.jpg

This version now uses the licensed text of the scriptures from the Church, which means I’m finally able to make editions in other languages. To start out, we’ve got French, German, Italian, Portuguese, and of course Spanish.

study-edition-spa-bofm-02.png

To make it easier to create versions of the study edition in other languages, I started over from scratch, using a set of Python scripts to pull the text from the files the Church sent me, then generate a LaTeX document that gets turned into the PDF. It’s a really nice workflow.

study-edition-eng-bofm-01.png

Over the next month or so I’ll be revising several of my other scriptures projects (reader’s edition, Words of the Prophets, etc.) to use the licensed text, with a similar Python-based workflow to make updates easier.

Also, if you’re interested in a study edition in a new language, let me know.

Bubbles

Playing around:

bubbles.jpg

I wrote the circle chording code on my phone in Pythonista, then ported it to PlotDevice, fleshed it out, and textured it in Photoshop.

I’ve renamed inkpdf to Press (as in printing press).

I reached the point where creating the PDF manually is no longer feasible, so I’ve been working on getting Press to a point where I can implement the PDF generation. The basic structure is in place, sans the PDF part. (That’s next.)

Here’s what a Press script looks like right now:

from press import Press

p = Press('output.pdf', width=6*Press.INCH, height=11*Press.INCH,
          margin=1*Press.INCH)

# Horizontal borders at top and bottom of page
p.stroke('#000')
p.pen(1.0)
p.line(p.page_min_x, p.page_min_y, p.page_max_x, p.page_min_y)
p.line(p.page_max_x, p.page_min_y, p.page_max_x, p.page_max_y)

# Page 2
p.page(2)
p.layer('base')
p.stroke(rgb=(1, 0, 0))
p.line(150, 150, 300, 300)
p.layer('fg')
p.stroke(hsl=(0, 0.5, 0.8))
p.line(300, 300, 450, 150)

# Go back and add another line to page 1
p.page(1)
p.stroke('#025')
p.line(p.page_min_x, p.page_min_y, p.page_min_x, p.page_max_y)

p.save() # this doesn't work yet

You can also do something like this:

with Press('output2.pdf', size=Press.LETTER,
           margin=(0.5*Press.INCH, 1.0*Press.INCH),
           inner_margin=0.5*Press.INCH,
           outer_margin=1.25*Press.INCH,
           bleed=.125*Press.INCH) as p:
    p.line(50, 50, 250, 50)
    # And so on

(Context manager, inner/outer margin, bleed, built-in paper sizes.)

Up next: adding more primitives, designing the font selection mechanism, getting it to generate an actual PDF, embedding fonts, using arbitrary Unicode code points, integrating HarfBuzz, etc.

Lifter is “a lightweight query engine for Python iterables.” Looks nice. One of their examples:

# vanilla Python
results = [
    user for user in users
    if user['age'] == 26 and user['is_active']
]

# lifter
results = manager.filter(User.age == 26, User.is_active == True)

Momentum

I’m getting back into blogging about in-progress projects, because otherwise I hardly blog at all. Expect posts soon about the following coding projects, all at varying stages of completion:

  • Vinci (notebook app)
  • Bookshelf (successor to Bookkeeper)
  • Codex (successor to Unbindery)
  • Quill (successor to Codex, sort of)
  • Storybook (writing app)
  • Speed (desktop writing app)
  • Liszt (todo list app)
  • Endless (mindmapping app)
  • Botswana 2 (revamp of Botswana)

Brief sidenote: I switched a while back to Python/Django, and I’m very glad I did. I can often get to a working prototype within only an hour or two. Back in my younger days I wanted to write everything myself from the ground up, but I see now that I was foolish. Life is short. I’d rather focus on the interesting parts — the app itself — and let the framework handle the routine grunt work.

Momentum

Momentum is the app I’d like to introduce today. It’s a web app written in Django, started back in January to help me track my goals.

More specifically, I wanted something that would help me spend more time reading scriptures and writing fiction. I don’t always have a free half-hour, though, so I needed something to track little bits of time throughout the day, and Momentum was born. I’ve been using it pretty much every single day since then.

Here’s what it looks like on my phone (with dummy data):

momentum.png

Some quick notes:

  • It currently supports tracking minutes, times, or words per day.
  • When I reach a particular goal, it disappears from the list for the rest of the day so I can focus on the goals I haven’t yet reached. (This is a change I made last night, actually.)
  • If I don’t make any progress toward a goal at all within a set time period, the goal goes stale and turns red. (There’s a system-wide stale period setting and each goal can also have its own.) I started using this staleness idea in Bookshelf (more on that in a later post) and it’s been motivating enough that I ported it to Momentum.
  • It supports folders. I have Projects and Health folders, where I have specific projects (stories/apps I’m working on), and things like squats and pushups.
  • Right now you have to add/edit goals via the Django admin. It works but isn’t as nice as something in-app. I just need to get around to doing this, since this is the main thing keeping it from being releasable.
  • The code is on GitHub as usual. Again, this is unreleased, in-progress code, YMMV, grain of salt, etc.