Home

String Interpolation Interpolation

May 21st, 2020

This is a quick one, but while converting my old cellular automata posts from Jupyter Notebooks to HTML I came across this function I wrote five years ago.

def make_rule(rule_name, k):
    rule_name = int(rule_name)
    rule_len = 2 ** k
    rule = [*map(int, bin(rule_name)[2:])]
    rule = [0] * (rule_len - len(rule)) + rule
    rule = rule[::-1]
    return rule

This is just meant to return a list with the \(2^k\) binary digits of the integer rule_name, reversed. So we get something like

print(make_rule(123, 3))
#[stdout]
[1, 1, 0, 1, 1, 1, 1, 0]

I purposefully did not use bit-shifting operations, yet still I don't like this code a lot. It has wonky things like

bin(rule_name)[2:]

Which is there to remove the '0b' that the function bin prefixes to its output. If I were writing that today I'd make use of the string format parameter b

x = 123
print(f"{x:b}")
#[stdout]
1111011

It's cleaner in my opinion, though admittedly a bit more cryptic if you're not used to string formating.

Then there's this line, which is meant to left pad the resulting string with zeros

[0] * (rule_len - len(rule)) + rule

I knew you could set the minimum number of digits n of a number using the formating parameter 0n

x = 123
print(f"{x:08}")
#[stdout]
00000123

but I didn't know if you could use both parameters in conjunction before writing this post. Turns out you can.

x = 123
print(f"{x:08b}")
#[stdout]
01111011

However in my case the number of digits is variable. I wonder if I'm allowed to...

k = 3
x = 123
print(f"{x:0{2 ** k}b}")
#[stdout]
01111011

Oh. So I could have written the function more succinctly.

def make_rule(rule_name, k):
    n_digits = 2 ** k
    as_binary = f"{rule_name:0{n_digits}b}"
    return [int(i) for i in reversed(as_binary)]

print(make_rule(123, 3))
#[stdout]
[1, 1, 0, 1, 1, 1, 1, 0]

Which I think is a bit nicer.

Comments on Reddit