Use the Alphabet

A deep index can get confusing. 1.1.1.1.1.2 makes it easy to forget or add a 1. Instead, I use 1.a.1.a.1.2. I can still make a mistake, but I make fewer mistakes.

This is the principle, and I'll swear by it until my last breath: do one thing. Do one thing at a time. Don't try and remember things, do math, think about the note I'm creating, think about whether it will be useful for something, or whatever. The better I am at focusing, the more effective my work.

integer_to_alpha[source]

integer_to_alpha(n, alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'])

Convert numbers > 0 to alphabetic representations. For the regular alphabet, 1 == a, 26==z, 27==aa, 52 == az, etc.

letter_to_value[source]

letter_to_value(letter, alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'])

Where does this letter fall in this alphabet?

alpha_to_integer[source]

alpha_to_integer(string, alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'])

Convert a string to an integer

short = list('abc')

assert integer_to_alpha(1, short) == 'a'
assert integer_to_alpha(2, short) == 'b'
assert integer_to_alpha(3, short) == 'c'
assert integer_to_alpha(4, short) == 'aa'
assert integer_to_alpha(7, short) == 'ba'

assert letter_to_value('a', short) == 1
assert letter_to_value('b', short) == 2
assert letter_to_value('c', short) == 3
assert letter_to_value('d', short) == 0
assert letter_to_value('A', short) == 0

# From 1 to a large number, if I convert the integer
# to an alpha, then convert it back, it matches.
for i in range(1, 1000):
    alpha = integer_to_alpha(i, short)
    result = alpha_to_integer(alpha, short)
    assert i == result

Making Sense

So, combining alphabets, but starting at 1 is useful for indexing. I'm not feeling confident that 1 == a is the place to start. Number systems usually find zero and negative numbers useful. This is a practical system, for indexing, and I'm not sure I know what 0 index in the sense of finding a note means, and I'm sure I don't need to do that.

Also, I like that I'm using the approach that Niklas Luhmann (1927-1998) orginally used. He had notecards in a box, I have notes in a directory. We both use this sort of indexing.

Increment Indexes

I index so I know where to stick the next slip.

1 becomes 2, 1.a becomes 1.b when we're just appending the next slip to the tree. This is next_index.

If I'm adding a slip that qualifies, challenges, or clarifies an idea, I often like to make it a child. So, a slip about the age of the Sphynx might be about the standard Egyptologists saying it was first constructed around 2,500 BC. If I wanted to use notes from Robert Schoch, the geologist, I'd add a child note that he claims they were built before 9,700 BC. So, the first note could be 3.c.2 and the second 3.c.2.a.

is_integer[source]

is_integer(o)

validate_index[source]

validate_index(current, separator='.', **kw)

Ensure the index can be iterated.

next_index[source]

next_index(current, separator='.', default='1', alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'], **kw)

Get the next value for an index. None returns '1', '' returns '1', 1.a returns 1.b, etc.

next_child[source]

next_child(current, separator='.', default='1', alphabet=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'], **kw)

Get the next child for an index. None returns '1', '' returns '1', 1.a returns 1.a.1, 2 returns 2.a.

assert next_index(None) == '1'
assert next_index(None, default="foo") == "foo"
assert next_index('-1') == '1'
assert next_index('') == '1'
assert next_index('1') == '2'
assert next_index(41) == '42'
assert next_index('1.a') == '1.b'
assert next_index('42.zsa.13') == '42.zsa.14'
assert next_index('2|b|3', separator='|') == '2|b|4'

assert next_child(None) == '1'
assert next_child(None, default="foo") == "foo"
assert next_child('-1') == '-1.a'
assert next_child('') == '1'
assert next_child(41) == '41.a'
assert next_child(41, alphabet=list('bcd')) == '41.b'
assert next_child('1.a') == '1.a.1'
assert next_child('42.zsa') == '42.zsa.1'
assert next_child('2|b|3', separator='|') == '2|b|3|a'
assert next_index('1.abc', alphabet=list('abc')) == '1.aca'

Making Sense

So, next_index and next_child are working as I'd expect. This version of the code is a LOT cleaner than the version I'm replacing. The other system used 20-30 functions and there were bugs in there I didn't have the patience to find.

I like the idea that most of these functions take a fairly robust set of parameters, so I can use a different alphabet or separator.

Filenames

For simplicity, I'm replacing shell whitespace characters with underscores, by default, but not dealing with other problematic input. I may just white list filenames later.

A default filename for "As Good As It Gets" attaching after 1.a would be 1.b.as_good_as_it_gets.md.

to_filename[source]

to_filename(s, reference=None, index=None, child=False, index_separator='.', title_separator='_', suffix='md', **kw)

assert to_filename('abc 123') == '1.abc_123.md'
assert to_filename('  ABC   123   ') == '1.abc_123.md'
assert to_filename('abc 123', title_separator='|') == '1.abc|123.md'
assert to_filename('abc 123', index='2.b.1') == '2.b.1.abc_123.md'
assert to_filename('abc 123', reference='2.b') == '2.c.abc_123.md'
assert to_filename('abc 123', reference='2.b', child=True) == '2.b.1.abc_123.md'
assert to_filename('abc 123', suffix='markdown') == '1.abc_123.markdown'

Making Sense

The idea is that titles and indexes combine to make filenames. I think I've captured a reasonable set of defaults.

This doesn't mean a filename will work with a POSIX operating system, on S3, or anyplace. It just means that an idea can be easily converted to a filename if I remember how I'm using this information.