pages / notes / 2022 / 2021 / 2020 / 2019 / 2018

Wallpaper: frost on leaves (winter)

Frost on plane tree leaves in a local park"

Leaves in a corner of a local park.

Cibo dal legno

Picture of an oven bread with chestnuts and mushrooms.

Food from the wood. Should it be bosco rather than legno? This is what you get for trusting Google Translate.


250g of Lidl Strong White Bread Flour (the upstart of urban baking), quarter tsp of salt, shake of rosemary seeds, mix in a large bowl. In a small bowl add a quarter of a teaspoon of dry active yeast and a pinch of flour to 170g of tepid water and stand for 5 minutes or so until some bubbles and a yeasty smell. Add the water/yeast into the flour in the larger bowl and mix to a rough dough. Rest 20 min. Knead for a few minutes and return to bowl with a tablespoon of olive oil to prevent sticking. Cover with a damp tea towel and let rise for 2 to 3 hours until doubled or tripled in volume.

Turn out into a small (12 inch by 8 inch) oven tray which has been oiled with 2 tbsp of olive oil. Pull out with fingers so dough roughly fills the tray. Flip the dough over to coat both sides with the oil. Leave to rise for an hour or so, perhaps a bit longer. Pre-cook the mushrooms and chop the (supermarket pre-cooked) chestnuts. Put the oven on high (gas 9/250 Celsius) after half an hour of the proof to pre-heat. Put the topings and a shake of salt and perhaps some dried tarragon on the dough and rest 10 minutes before putting in the oven.

Cook on a shelf in top quarter of the oven for 15 mins and check for golden brown top. Allow to cool (might need careful use of a spatula to remove from the tray) and slice and eat with salad (apple and berries to continue the woody theme, plus dips such as tahini beaten with water).

Pesto pasta

30g pack of fresh basil washed and chopped. Chop 30g walnuts with a table spoon of pine kernels and some mixed seeds. Toast the nuts dry in an iron skillet for a few minutes. Blend the basil, nuts with about 60ml of olive oil (I use the coffee grinder attachment on my Philips blender) to a thick paste. Add salt and pepper to taste. Set aside while pasta cooks.

A minute or two before the pasta is fully cooked, reserve a few table spoons of the pasta water and drain the pasta and add back to pasta pan on very low heat. Add pesto and the reserved pasta water and stir for a minute. Serve with tomato and cucumber salad and perhaps some hard cheese.

CentOS Linux gone

TL;DR: Used to be Fedora -> RHEL -> CentOS Linux. Now Fedora -> CentOS Stream -> RHEL -> Sources on centos.git -> Other clones not owned by Red Hat. So basically Fedora is like Debian Sid, CentOS Stream is like Debian testing and RHEL is like Debian stable but you can't have RHEL unless you pay for a licence. Source code released as a lump and clones can pick it off and build their own stable versions.

Replaced by CentOS Stream acting as a beta for RHEL apparently with tested packages going into RHEL, so CentOS Stream is upstream to RHEL for functionality based software version upgrades but simultaneously downstream from RHEL for security updates. Very quantum entanglement.

Not quite sure what this means, but I suspect that CentOS 8 won't be the usual very stable server OS it has been from when CentOS Linux 8 is withdrawn in favour of CentOS Stream 8 (or whatever). It certainly can't be seen as an functionally identical RHEL clone any more.

Keep an eye out for another recompile project - the RedHat manager type on the mailing list has confirmed that RHEL sources will still be pushed out via the github accounts.

Johnny Hughes is steadfastly maintaining that nothing much has changed and that CentOS will get its security updates from RHEL as usual after QA. Others not convinced, pointing to change in the status of CentOS 8 after only 2 years (usually 10 years before EOL). The manager type is suggesting that people look at RHEL for production servers...(and we know how that went down last time).

There are two other RHEL clones left standing, Oracle Linux (install media direct link) and Springdale linux (Springdale Version 8 boot images only as they use local repos when doing their installs).

Very few positive views on this from anywhere.

Wallpaper: snail in the hedge

Widescreen wallpaper with a snail sitting on evergreen hedge foliage.

Hedge on Church Road in Moseley. Snails in the foliage, a few of them.

Where is the moon now?

Below is a stunningly literal c program that provides the moon command. Running moon tells you the altitude, azimuth and phase of the moon at the current Unix time.

Plans include: specifying latitude and longitude as arguments to the command instead of being compiled in the source a la dwm; adding the time (in local time zone) of the next rise/set event; adding position angle of bright limb; adding optical librations (physical librations well below precision of the position routines); adding a list of craters with good visability on terminator; adding references to Rukl maps for the terminator; allowing the specification of times other than current time.

/* cc moon.c -lm -o moon */
/* alt az and phase of moon *now* on a Unix-like OS */

#include <stdio.h>
#include <time.h>
#include <math.h>

/* Your latitude and (east) longitude */
#define LONG -1.903
#define LAT  52.4797

/* Some constants */
#define J2000 946728000 /* J2000.0 in seconds since Unix epoch */    
#define RADS 0.0174532925199433
#define DEGS 57.2957795130823
#define PI 3.14159265358979

double range(double y);

int main(void) {

time_t now;
double d, t, lambda, beta, paralx, ut, utdays;
double l, m, n, alpha, delta;
double x, y, z, x1, y1, z1;
double theta, talpha, tdelta, r, tr, tparalx;
double ha, x2, y2, z2, xh, yh, zh, alt, az;
double L, g, slambda;
double elong, pa, phase;

/*  Get Unix time in seconds UT then find
    days and Julian centuries since J2000.0 */

    now = time(NULL);
    if (now == -1) {
        puts("The time() function failed");
/*    printf(" unix time: %d\n", now);      */

    d = (now - J2000)/(86400.0); /* days since J2000.0 */
    t = d / 36525.0;

/*  Most of calculations below from Astronomical Almanac
    page D46 'Low-precision formulae for geocentric coodinates
    of the Moon */

/*  Geocentric ecliptic coords of Moon */

    lambda = 218.32 + 481267.883 * t;
    lambda += 6.29 * sin(RADS * range(134.9 + 477198.85 * t));
    lambda -= 1.27 * sin(RADS * range(259.2 - 413335.38 * t));
    lambda += 0.66 * sin(RADS * range(235.7 + 890534.23 * t));    
    lambda += 0.21 * sin(RADS * range(269.9 + 954397.70 * t));
    lambda -= 0.19 * sin(RADS * range(357.5 +  35999.05 * t));
    lambda -= 0.11 * sin(RADS * range(186.6 + 966404.05 * t));

    beta = 5.13 * sin(RADS * range( 93.3 + 483202.03 * t));
    beta += 0.28 * sin(RADS * range(228.2 + 960400.87 * t));
    beta -= 0.28 * sin(RADS * range(318.3 +   6003.18 * t));
    beta -= 0.17 * sin(RADS * range(217.6 - 407332.20 * t));

    paralx = 0.9508;
    paralx += 0.0518 * cos(RADS * range(134.9 + 477198.85 * t));
    paralx += 0.0095 * cos(RADS * range(259.2 - 413335.38 * t));
    paralx += 0.0078 * cos(RADS * range(235.7 + 890534.23 * t));    
    paralx += 0.0028 * cos(RADS * range(269.9 + 954397.70 * t));

/*  Geocentric RA and Dec of Moon
    The D46 page uses fixed value 23.44 deg for 
    obliquity of ecliptic */

    l = cos(RADS * beta) * cos(RADS * lambda);
    m = 0.9175 * cos(RADS * beta) * sin(RADS * lambda); 
    m -= 0.3978 * sin(RADS * beta);
    n = 0.3978 * cos(RADS * beta) * sin(RADS * lambda); 
    n += 0.9175 * sin(RADS * beta);
    delta = asin(n);
    alpha = atan2(m,l);

/*  Topocentric RA and Dec of Moon
    From Astronomical Almanac, D46
    'Low precision formulae for topocentric
    coordinates of the Moon'              */

    r = 1 / sin(RADS*paralx);
    x = r * l;
    y = r * m;
    z = r * n;

/*  Local sidereal time needed for next stage       */
/*  UT from the Unix time count as fraction of day
    utdays isn't used anywhere                      */
    ut = modf(now / 86400.0, &utdays);
/*  D46 page simplified formula for LST             */
    theta = range(100.46 + 36000.77 * t + LONG + ut*360);
    printf("       LST: %3.0f\n",theta);

/*  Vector subtraction for our position on Earth sphere */
    x1 = x - cos(LAT * RADS) * cos (theta * RADS);
    y1 = y - cos(LAT * RADS) * sin (theta * RADS);
    z1 = z - sin(LAT * RADS);
    tr = sqrt(x1 * x1 + y1 * y1 + z1 * z1);

/*  Topocentric Dec and RA */
    tdelta = asin(z1 / tr);
    talpha = atan2(y1, x1);

/*  Horizon coordinates of Moon. See
    for formulas */

    ha = theta * RADS - talpha;
    x2 = cos(ha) * cos(tdelta);
    y2 = sin(ha) * cos(tdelta);
    z2 = sin(tdelta);

    xh = x2 * sin(LAT * RADS) - z2 * cos(LAT * RADS);
    yh = y2;
    zh = x2 * cos(LAT * RADS) + z2 * sin(LAT * RADS);
    alt = asin(zh);
    az  = atan2(yh , xh) + PI;
    printf("  altitude: %3.0f\n", alt * DEGS);
    printf("   azimuth: %3.0f\n", az * DEGS);    

/*  Ecliptic longitude of Sun using page C24 from AA */
    L = range(280.461 + 0.9856474 * d); 
    g = range(357.528 + 0.9856003 * d);
    slambda = L + 1.915 * sin(RADS * g) + 0.020 * sin(RADS * 2 * g);

/*  Phase of Moon from */
    elong = acos(cos(RADS * (slambda - lambda)) * cos(beta * RADS));
    pa = PI - elong;
    phase = ( 1 + cos(pa) ) / 2;
    printf("     phase: %3.0f\n", phase*100);

    return 0;

/* returns an angle in degrees in the range 0 to 360 */
range(double x) {
        double a, b;
        b = x / 360;
    a = 360 * (b - floor(b));
    if (a < 0)
                a = 360 + a;

Autumn Leaf

Shrivelled leaf on pavement

My current wallpaper on the old Thinkpad X61s. Right click and view image for the full 1024x768 pixel size.

We are sliding down the ecliptic into Winter with the Solar longitude in the mid to high 200s. These days in the UK winter is grey wet and rainy rather than crisp and frosty with some snow.


Picture of building in Great Newhall Street, Birmingham. My eye caught a point of light or gleam on the third floor.

Close up: either a mirror or the back window into a light well. Investigations continue.

It is a great disappointment to me that the upper floors of these stupendous buildings lie neglected. They could be rented as substantial flats so easily. There is some activity further out from the town centre but not here. Many are store rooms for shops below filled with damp cardboard boxes that never seem to move from decade to decade. Others are basically pidgeon lofts left unglazed. We prefer to build 51 story investment opportunities in the centre rather than build viable neighbourhoods.

Yeast boule

My universal bread recipe using yeast with 100g of Gilchester's Organics spelt and 400g (urban chic) Lidl strong white bread flour. Shaped to boule, 1h proof in a basket and 40mins bake in a cast iron casserole. Rose ok and smells nice.

A 100% wholemeal spelt loaf raised with my sourdough starter using a straight through recipe (500g flour, 350g water, 2 tbsp/40g starter, half tsp salt) with the Gilchesters spelt was very tasty and lovely toasted but did not rise a lot. Think rye without sticky enzymes and you get the picture. 18h rise and 2h proof in a bread tin. The result was a 'pudding' or pumkernickel style crumb. Loaded with mixed seeds and chopped walnuts.

The hairy bikers have done a Gilchesters spelt loaf recipe: poolish then main ferment supported with honey! I'll be trying the Gilchesters wheat if the local stockist has some left next time I go. I like the idea of a wheat field in Northumberland, grinding on the farm and shipping out to punters. The flour certainly feels different to supermarket flour.

City Centre Views

Not sure what Jane Jacobs would make of the new city centre. The neighbourhoods went 30 and 40 years ago, I arrived in Birmingham just as the Snow Hill area was being pulled down and being replaced by car parks and ring road plant, itself pulled down now.

Generational shift?

What I want to know is this: why can't I draw a flowchart or write a specification in some kind of pseudocode and then photograph it with my phone and have that turned into working code on a Web interface somewhere? Basically this is the third decade of the 21st century and where is my jet car?. Why did we give up on augmenting minds?

Back to Gedit (cursor bar that sits between two characters) and C. Nano has its uses when ssh-ing into a Web server.

Looking at VS Code for Python. It is an electron application so will probably drain the batteries/melt the processor but I'll be down with the kids and dad-dancing for a bit.

Autumnal Equinox

Definition of the seasons from my old copy of Smart

Here is a spreadsheet that will calculate the dates and times of the solstice and equinox events for any year from 1 000 to 3 000...

Dates are given in the Gregorian calendar from 1581 onwards (use with caution for English historical dates between 1581 and 1721). Errors are less than a minute of time between 1951 and 2050, likely to see us through!

The routines were taken from Astronomical Algorithms by Jean Meeus, first edition, 1991, published by Willmann-Bell.

The solstice or equinox event is defined as the instant when the apparent geocentric longitude of the Sun is a multiple of 90 degrees. Apparent means including the effect of aberration (doppler shift of position due to motion of the Earth in its orbit) and nutation (‘nodding’ of the Earth as the axis of rotation shifts a bit mainly due to the Moon’s motion).

The spreadsheet calculates the mean Julian day for each event, and then sums a ‘fourier series’ of correction terms for each event in the year. The coefficients in each of the terms are calculated to fit data generated from the equations of motion of the solar system.

This whole post is recycled from posts in 2007 and 1990s. Not bad eh?

Dip with cannelini beans and tahini

This was improvised the other night on the theme of moutabel and baba ganoush in the absence of an actual aubergine (aka egg plant). Serves two as part of a starter.

The method, insofar as there is one is simple: mash everything together with the back of a spoon in a good thick flat bottomed bowl. I tend to mash the cannelini beans in their water and lemon juice first, then add the tahini and whip up into that strange mayonnaise-like consistency that tahini does when mixed with water. Then add the spices. Serve with bread, salad and anything else you fancy.

Five Ps

Getting to know the local parks very well. A photo of a patch of clover in Adderley park. I have not been eating out at all since Feb. City centre coffee and breakfast place hanging on in there. I've always liked the theme and interior design. Just part of a small chain.

The virus spreads through

people in
poorly ventilated,

This is not all or nothing, every little helps. Reduce one or more of the Ps and we all benefit. Winter is coming.

Driven by the science

"The kernel of indisputable information is a dot in space; interpretations grow out of the desire to make this point a line, to give it direction. The directions in which it can be put by a culturally, professionally, and geographically diverse society, are almost without limit."

The quote is from Barry Lopez, Arctic Dreams, page 127 in the UK Vintage Classics edition. It occurs in the context of a mismatch between Inuit perceptions of the behaviour of animals and scientific research efforts.

It strikes me as a useful guide to the current pandemic three step (Hungarian rhythm[*]) dance between the government, the (applied) scientific experts and the media. We have a highly politicised use of scientific results and predictions to make policy that affects millions of people. Not only (prudent) restrictions on basic liberties but also imperatives to return to specific locations in order to work, and to regulate interaction with others, so meetings in the garden are banned but the pubs can stay open!

The experts are asked to take as inputs certain policy assumptions...

I am wondering who the winners and losers in this game are going to be.

[*] aka 'in a limping way', one-two-three one-two...

Wrangling text dumps

So I want to keep the text of a Web page to refer to later, or perhaps print out and annotate. I use links, sed, fmt and troff as below...

$ links -dump -width=60 > text.txt

Links dumps the rendered text out, but pads each line with spaces before the text, so I get rid of those and reformat and add troff paragraph markers to each blank line...

cat text.txt | sed -e 's/^[ \t]*//' | fmt | sed 's/^$/.P/' >

Edit the file to get rid of all the navigation junk from the Web pages (50+ lines of it sometimes) and to add the url and date accessed. Below are the requests that I put at the top of the file that turn off hyphenation, set the text right ragged, and provide a bit more interlinear spacing than normal (12pt on 18pt or even 14/24). The last request sets the default paragraph type to indented. Delete that line (or just change the number to 0) if you don't want indents.

.nr Hy 0
.SA 0
.S 12 18
.nr Pt 2

Then produce a pdf file using [GNU]troff...

groff -mm  -Tpdf > text.pdf

The sed/fmt command needs thinking about but the current copypasta works ok for now. Less hassle than copying into OpenOffice Writer or Abiword and fidding with the hard wraps.



Both doughs were 450g strong white bread flour (lidl), 50g wholemeal spelt (inevitably Dove's Farm as they have the supermarkets sown up for distribution since Matthews apparently went online), 350g water and half a teaspoon of Alison's dried active yeast added to the water to activate it. I use half a teaspoon of salt, but the usual recipe would be one and a half teaspoons. I don't add olive oil to the dough. I keep it for dribbling onto thin slices...

Knead to rough dough, rest for half an hour, attempt to knead 'French style' (fold and slap), and rise for three hours or so then divide for two small slippers. Let them proof for about an hour (warm oven part way through). I used my thin sandstone pizza stone. Could have used a pizza pan with polenta as suggested on the link below but I always find that the polenta carbonises and smells. 20 mins in oven on Gas 9 which tops out around 240 C.

Idea came from a page where the author tries four shaping methods and assesses the impact on the crumb (spoiler: none).

Both shapes rise vertically so you end up with three inch thick loaf. I prefer the envelope style shape (left image).

The increasing number of options to command line programs over time

Plot of the number of options for various Unix commands against time. The vertical axis is logarithmic.

"I've never used some of the options we've discussed and only rarely use others, but that's the beauty of command line options -- unlike with a GUI, adding these options doesn't clutter up the interface. The manpage can get cluttered, but in the age of google and stackoverflow, I suspect many people just search for a solution to what they're trying to do without reading the manpage anyway."

From an article on The table of numbers of options for four typical releases of a unix like operating system caught my eye. Above is an attempt at a graphical representation. I'm not sure if it adds much value and may actually be confusing. Sometimes a table is better.

Table data copied into OpenOffice and converted using the 'text to columns' wizard. You can't have zero values on a log graph so I fudged those using 0.1 as the value. I could have added 1 to all the data claiming I was counting arguments to the command!

Grades Hassle: a tale of three schools

Imaginary School A 
pass rates from 2014 to this year, 66, 71, 72, 67, 66, 60 Imaginary School B pass rates 
from 2014 to this year, 67, 68, 68, 69, 71, 73 Imaginary School C pass rates from 2014 to this year, 67, 68, 67, 
67, 69, 68

The chart fragments above show the pass rates in GCSE maths for three completely imaginary schools from 2014 to 2020. The vertical axis starts at 50% and tops out at 90%.

The human mind loves narratives.

Take a minute and encapsulate the trend for each school in a pithy sentence for the Govenors committe and the Parent Teachers Association...

Punchline: They are Random!

In fact each school's history has been simulated.

The simulation spreadsheet uses a cell to represent each pupil's exam result with the formula...

=IF(RAND() < 0.33;"f";"p")

...where 0.33 is the probability that the student fails first time around based on the nationally agregated pass rate. Mash F9 repeatedly and roughly two thirds of the time your pupil will pass and one third of the time they will have to retake.

Each column is a year.

Copy down 240 rows of the formula above, so 240 pupils roll their individual and slightly loaded dice. The 'pass rate' for that year is calculated using...

=COUNTIF(B26:B265;"p")/240 * 100

Then you copy across for as many 'years' as you want to form the history of the school.

The rows at the top of the spreadsheet are left for inserting a graph. Pressing F9 will repeat the whole history (or manufacture a new school). Each graph will look different, and will show a different 'trend' but represents an equally likely outcome consistent with the overall national pass rate.

Keep mashing the F9 key and sooner or later you end up with a history that will get the Principal a knighthood, or perhaps result in early retirement and a rapid academisation!

The GCSE Maths pass rate hovers around two-thirds most years (actually since I was a teenager sometime last century if you include CSE grade 1 as pass and allow for O levels). Your typical inner city comprehensive has 8 forms in each year and about 30 pupils per form. In my magical simulation noone joins or leaves half way through the year, and we never allow classes larger than 30.

So much of what we do is managing noise.

So much politics and controversy comes from the lack of experience with the behaviour of small samples.

Bash pipelines - most common words

The pipeline below will tell you the 20 most common words in a text file. It will give you the frequencies of each word.

cat textfile |
 tr '[:upper:]' '[:lower:]'  |	# force capitals to lower
 grep -o -E '\<[A-Za-z]*\>' |   # one word to a line ignore spaces, symbols, numbers
 sort |                         # sort alphabetical order
 uniq -c |                      # remove duplicates but count frequencies
 sort -rn |                     # reverse sort on frequencies
 head -n 20                     # print first 20 lines of output

Sample output based on a thousand words or so of descriptive text...

     76 the
     44 and
     39 a
     24 of
     24 in
     20 was
     18 with
     16 that
     15 i
     14 to
     11 as
     10 on
      8 he
      8 but
      7 have
      7 for
      6 some
      6 or
      6 not
      6 bright

Replacing the call to head in last line of the pipeline with wc -l will tell you how many different words you used. Actually, you could miss off the last sort as well so the command becomes...

cat textfile |
  tr '[:upper:]' '[:lower:]'  |
  grep -o -i -E '\<[A-Za-z]*\>' |
  sort |  uniq | wc -l 

All good copypasta from Stack Exchange. I need to build some regular expressions myself and get my head around shell quoting.

Starting from the bottom up...

Writing each day with no big plan or structure in mind. Not ready for John McPhee's cards yet, not even sure if there is a theme. So I'm keeping notes quite small, backing up to external storage often, and playing with structures and content. Could just be a way to pass time in the (ongoing, sortof) lockdown.

This is just the start so no expectations and just writing '20 lines a day, genius or not' with the emphasis on not.


The functions below are in my .bashrc file. The first two are from

function n {
  if [ -n "$1" ]; then
    leafpad ~/Documents/notes/$
    echo "Usage: n <title>"

I usually invoke n with a meaningful title with underscores instead of spaces - I should automate that bit with a sed statement somewhere. Markdown may not be the ultimate format - could use groff with mom macros. But whatever I use will be accessbile for the forseeable future because written in plain text files with some tagging.

The search function ns works but needs a bit of work. Because I use leafpad with dynamic word wrap as the editor, there is usually sufficient context on free text search results.

function ns {
  if [ -n "$1" ]; then
    echo "Matching note names:"
    ls -c ~/Documents/notes | grep -i $1
    echo "Matching content:"
    grep -i $1 ~/Documents/notes/* | sed 's/^.*\/Documents\/notes\///g'
    ls -l ~/Documents/notes

The search function can be used to implement basic tagging by adding tags with something like $TAG: and a list of tags at the end of each file.

I have a cumbersome and inefficient versioning function that just copies all the files in the notes directory to a sub-directory called .versions with the date and time appended to all the file names. Then it loads leafpad so I can type a log entry for that particular version.

function n-version {
datenow=$(date +%Y%m%d-%H%M)
cd ~/Documents/notes
for f in *
   cp -v "$f" ~/Documents/notes/.versions/"${f%.}"_$datenow
touch ~/Documents/notes/.versions/~version_$datenow
leafpad ~/Documents/notes/.versions/~version_$datenow
cd $dirnow

Note added 30th August. I added a function that copies the current state of a single named file to a special .drafts folder. You can save a draft of a file in the main notes folder and then edit it, so you have a previous version to fall back on. This function needs to be storing incremental diffs rather than the whole file each time, something I'll add soon. Then I can replace the n-version function with one that just makes a draft of all the notes, so the whole scheme becomes incremental.

function n-draft {
datenow=$(date +%Y%m%d-%H%M)
cd ~/Documents/notes
   cp -v "$1" ~/Documents/notes/.drafts/"$1"_$datenow
cd $dirnow

Messy but it works for now and text files don't take much space after all. It is easy to copy a complete set of files corresponding to a version somewhere and then chop off the times. Perhaps renaming files with their hash function then making a file with the version date with a list of the hashes corresponding to that date would be better (no duplication of unchanged files) but then I'll need functions to extract all the files belonging to a version and to restore their original names. At that point may as well just use git.

Backup to web space (5Gb server space and my little Web site is using rather less than 1 Gb)

function n-up {
lftp -u user,passwd <<EOF
set ssl:verify-certificate no
set sftp:auto-confirm yes
mirror -R --verbose -c --verbose /home/keith/Documents/notes /home/user/notes

9th August: for some reason that I cannot fathom, the function above continues to upload the entire contents of .versions even though the files have not changed. I've redefined n-up in .bashrc as follows...

alias n-up="rsync -av ~/Documents/notes/" will be prompted for the password. It might be worth mentioning that the remote ~/notes directory is above the Web page directory and not accessible from the Web directly. My shell account includes ssh access.

Restore from Web space...

function n-down {
lftp -u user,passwd <<EOF
set ssl:verify-certificate no
set sftp:auto-confirm yes
mirror --verbose -c --verbose /home/user/notes /home/keith/Documents/notes;

The nice thing about lftp is that it only uploads the changed files, when it feels like it. Seems to be quite random though. If you have shell access, use rsync over ssh as mentioned above.

And the rsync version of n-down is...

alias n-down="rsync -av ~/Documents/notes/"

The rsync versions of n-up and n-down work really quickly.

It's all duct tape and coathangers at the moment but if something emerges, I'll take the time to refine it. The whole thing is tentative and light weight and can be abandoned if it isn't fun or working out.

Light on processes...

bash-4.2$ pstree -c
     |                     `-twm
     |       `-udevd

Stopped the dbus/messagebus and consolekit processes on a Slackware 14.1 installation for lutz. An X Windows session runs in something like 90Mb, with a minimal twmrc. Firefox 45 so switched Javascript off in about:config and using a hosts file to block ad servers. No printing and no auto-mount of USB sticks, so using Rox filer instead of Thunar (no extra dependencies for Rox Filer). ACPI runs but upower can't provide reports so just cat /proc/acpi/battery/BAT0/state to find how much juice left. Nice and quiet. Slow and deliberate.

(The laptop I do my work on has a full install and does Zoom and Teams because they are expected in this new world of ours.)

Phone pix

A set of three images off my phone.

View down my old school microscope of a leaf with silver fibres that Ruth picked up. A blackberry plant growing its way out of the fence. A bus stop's acrylic window provides a canvas...

Book markup for groff

Typeset the source below with something like...

$ groff -Tpdf -e -t -p -mom > book.pdf

and you will get a basic book layout. It took me some time to work out where the .COLLATE macro was hiding - in plain sight! Gnu groff is available in most distributions either in base or easily installable. Takes about 20Mb and compiles anything in a single pass - less setup than LaTeX. It is a typesetting package. The mom macros add some semantic structure on top.

\# DOCTYPE must be chapter for the collate to work
\# Metadata below used for cover sheet and running headers
.TITLE    "The Book"
.SUBTITLE "A demonstration"
.AUTHOR   "Tristram Shandy"
\# Alternative to TYPESET is TYPEWRITER 
\# None defined yet
\# Uncomment below for right ragged 
\# This puts the contents at the front
\# Define a range of section headings
\# This redefines the paragraph macro to be a blank line
.blm PP
.CHAPTER_TITLE "The first bit"

The ancient \fCgroff\fR typesetting package is the GNU
version of \fCtroff\fR. It is available for most Linux and
Unix like operating systems. In many distributions the
system is available within the default install.

This document is to remind me how to lay out a book 
in \fCgroff\fR using the \fCmom\fR macro package.

.CHAPTER_TITLE "A second helping"
You have to use the \fC.COLLATE\fR macro together with the
title and the \fC.START\fR macro for each chapter.
.HEADING 1 "A main section within the chapter"

Sections and sub-sections and so on are available for use
within the chapters. Don't put a blank line above a
\fC.HEADING\fR macro. You get extra space.

See how the first paragraph after the heading is blocked
while this second paragraph is indented?
.HEADING 1 "Headings need their titles"
Another heading 1 subsection.

Sourdough starter

Put a new starter on now we have regular supplies of bread flour. All done with a bag of Lidl strong white bread flour (59p) and a tablespoon of wholemeal bread flour.

Day 1: 50g of flour and 50g of water in a 1lb jar with a few holes punched in the lid. Mix well and leave for a couple of days for fermentation to start. Check a couple of times a day. I used some old rye flour left in a bag as part of the 50g. Anything wholemeal (even oats) will have wild yeasts present. Slight sweet smell and bubbles is what you are looking for.

Day 2 (which could be up to 48 hours or so after Day 1): Add a further 50g of (strong white) flour and 50g water. Mix again. Total weight of starter now 200g. Might be quite lively - mine reached the top of the 1lb peanut butter jar I'm using. It will fall back.

Each subsequent day up to around Day 10: pour 100g of mixture out and discard. Add 50g of flour and 50g of water. Mix well. Check for rise in level and bubbles 6 to 8 hours after feeding.

Around Day 9 or 10 or a bit longer, should smell like emulsion paint - slightly sharp but floury - and have a good range of bubbles. Bake a loaf risen with 2 tablespoons full of starter (about 30g) added to the water for the recipe and supported by a bit of sugar or honey or barley extract. Discard another 70g or so and feed with 50g of flour and 50g of water. Starter can now be kept in the fridge and fed twice a week.

The loaf I did yesterday had 250g Alison's very strong white bread flour, 250g Alison's wholemeal bread flour, 300g water with half a tablespoon of barley extract and 2 tablespoons of starter added. Plus salt, rosemary seeds and poppy seeds to taste. Kneaded 10 mins and left to rise for 5 hours. Shaped and proof in 2 hours. Baked for 20 mins high and 20 mins at gas 7. Nice loaf - not quite as high a rise as yeast based with same flours so leave a bit longer to prove next time.

Installing texlive from the iso on Slackware

I have standardised on a full install of texlive 2018 for what is likely to be a book length project. This note explains how to do a full install of texlive from the iso without having to burn an optical disk on Slackware 14.2 based on a stack exchange answer for Ubuntu.

The first stage is to unstall the (ancient) tetex installation in the Slackware 14.2 base...

# removepkg tetex

Then you need to

Assuming that the iso is in ~/Downloads/slackbuilds/texlive...

 # mkdir /media/iso                           # Create a mount point
 # mount -o loop texlive2018.iso /media/iso/  # Mount the image
 # ls /media/iso                              # Check its there!
 # cd /media/iso                              # Easier to run installer from root of the image
 # ./install-tl                               # Run the texlive package install script

...and go and make a cup of tea (a full installation uses up about 6Gb of drive space and takes around 10 to 15 mins on a laptop with an SSD).

Once the installer script completes, it prints a message that includes recommended paths. I add these to my .bashrc as follows...

 bash-4.3$ cat ~/.bashrc

I then test out the installation using a .tex file. If everything looks OK I unmount the iso and delete the mount point...

 # umount /media/iso                          # unmount the image
 # rm -rf /media/iso                          # careful!

Ground Marks

Today's long walk: some small details noticed.

Slackware 14.1 with up to date Firefox

Slackware64 14.1 is quite old now (released Nov 2013) but still receives security updates. I'm using a more recent Firefox to keep the laptop reasonably secure until the inevitable upgrade which I am postponing until after Slackware 15 is released.

Install Firefox-esr from the binaries

Recent versions of Firefox cannot be compiled from source with the tools in Slackware 14.1. Fortunately, Mozilla provide a binary download of Firefox that contains a range of private copies libraries within the tar file. You get a lot of duplicated hidden libraries and cruft but you can run the recent more secure browser versions.

I use the Firefox-ESR build, currently at 68.8, which runs fine under Slackware 14.1 when unpacked and used from a home directory or when moved to somewhere like /usr/local/firefox or /opt/firefox. The 'consumer' Firefox (currently version 76) works as well but I prefer the slower cadence of the ESR version.

Just download the Mozilla Firefox .tar.gz file and then...

$ tar xvf firefox-68.8.0esr.tar.bz2
# mv firefox /opt/
$ ./opt/firefox/firefox #test it runs ok

Add a custom desktop file so that you get the Firefox entry and icon in the Applications Menu | Internet section of the menu...

$ cat .local/share/applications/firefox.desktop
[Desktop Entry]
Comment=Custom definition for Firefox

Install Pulseaudio and codecs from SlackOnly

Recent versions of Firefox require pulse audio under Linux for replay of sound or video streams. Slackware 14.1 base does not include pulseaudio within the base system so you must install it as a slackbuild. When Slackware 14.1 was released, certain audio and video codecs could not be redistributed for patent and copyright reasons. They must be installed from slackbuilds.

You can compile the slackbuilds from source by downloading the SlackBuild scripts and the source code. This can be a time consuming process, but in return you get control over the options that are enabled and that in turn governs the number of compile and run time dependencies it is necessary to install. An alternative is to download precompiled binaries from a repository that you are prepared to trust. I use SlackOnly for 14.1 and 14.2 slackbuilds and have found their binaries to be fine but sometimes they set a number of the options in the SlackBuild script that bring in more dependencies.

To install pulseaudio on Slackware 14.1 with xfce4 as the desktop environment, I followed the five steps below...

Packages for pulseaudio with dependencies indented to show sub-dependencies. Links made to to SlackOnly 64 bit binary packages.

The pavucontrol package and dependencies in addition to those for pulseaudio...

The xfce4-volumed-pulse, pasystray and alsa-plugins packages have no additional dependencies...

The .asoundrc config file...

$ cat .asoundrc
pcm.pulse {
    type pulse

ctl.pulse {
    type pulse

pcm.!default {
    type pulse
ctl.!default {
    type pulse

Slackware 14.1 needs some extra codec packages to play YouTube videos and some kinds of streaming (e.g. parliament television in the UK and to join in some conferencing systems). I installed gst-plugins-bad and gstreamer-plugins-ugly...

Elephant Atta: Medium with multigrain makes a nice loaf

Elephant Atta: Medium with multigrain flour makes a nice loaf. I suspect that this particular flour is aimed at a UK market as it needs noticibly less water than most recipes for chapattis. I bought a 1.5Kg bag of this on my weekly shop in the local Morrisons'. The flour is finer than ordinary wholemeal with less of the larger jagged brown bits of kernel. The extra tiny percentages of non-wheat grains give a nice flavour to the loaf.

The recipe for a whole meal loaf is...

I mixed to a fairly slack dough, rested it for 20 mins to let the yeast start, then kneaded for 10 minutes. The dough is quite 'rippy' but gets slightly more pliable as you knead. 4 hours first rise, shape to tin loaf, roll in barley flakes, and then prove in the loaf tin for just under 2 hours until rises above top of tin. Bake 20 mins on Gas 9 (roughly 240°C in my oven) and then 20 mins on Gas 7. Turn out onto rack and allow to cool. Tasty and toasts well. Ruth wants another loaf today.


Straight through sourdough

Based on a recipe by Emmanuel Hadjiandreou, but with a much lower hydration (60% instead of his 76%). You get smaller bubbles but a more manageable dough for a tin loaf. The key to this recipe is time. Allow 12 to 18 hours for first rise and 3 to 5 hours for proofing in the loaf tin.



Every little helps

halve your interactions and reduce possible infections by a factor 
of about 40 after 20 days halve your interactions and reduce possible infections by a factor 
of about 40 after 20 days

The spread of a virus is not like a flood.

In a flood, if you are one sandbag too short, then the banks burst and your house is lost. In the attempt to slow the spread of the corona virus, every action by everyone helps reduce R0 a little bit. It is never too late to start. This is not all or nothing.

If you just skip one bus ride per day, that will help. If you wash your hands before and after using public transport, that will help. If you skip that totally pointless all staff meeting that will help. Try phoning intead of going.

If the social interaction graph can be halved from 2.5 infections per 6 days to 1.25 infections per 6 days, the result is a reduction by a factor of 40 after 20 days, and a much better chance of the NHS coping.

The graphs above were generated using an exponential function (assuming the same social interaction figure per person for each 6 day period). See formula view starting from A1 below...

Exponential function with various values of growth					
t	0.625	1.25	1.5	2	2.5
0	=EXP(B$3*$A4/6)	=EXP(C$3*$A4/6)	=EXP(D$3*$A4/6)	=EXP(E$3*$A4/6)	=EXP(F$3*$A4/6)
2	=EXP(B$3*$A5/6)	=EXP(C$3*$A5/6)	=EXP(D$3*$A5/6)	=EXP(E$3*$A5/6)	=EXP(F$3*$A5/6)
3	=EXP(B$3*$A6/6)	=EXP(C$3*$A6/6)	=EXP(D$3*$A6/6)	=EXP(E$3*$A6/6)	=EXP(F$3*$A6/6)
4	=EXP(B$3*$A7/6)	=EXP(C$3*$A7/6)	=EXP(D$3*$A7/6)	=EXP(E$3*$A7/6)	=EXP(F$3*$A7/6)
5	=EXP(B$3*$A8/6)	=EXP(C$3*$A8/6)	=EXP(D$3*$A8/6)	=EXP(E$3*$A8/6)	=EXP(F$3*$A8/6)
6	=EXP(B$3*$A9/6)	=EXP(C$3*$A9/6)	=EXP(D$3*$A9/6)	=EXP(E$3*$A9/6)	=EXP(F$3*$A9/6)
7	=EXP(B$3*$A10/6)	=EXP(C$3*$A10/6)	=EXP(D$3*$A10/6)	=EXP(E$3*$A10/6)	=EXP(F$3*$A10/6)
8	=EXP(B$3*$A11/6)	=EXP(C$3*$A11/6)	=EXP(D$3*$A11/6)	=EXP(E$3*$A11/6)	=EXP(F$3*$A11/6)
9	=EXP(B$3*$A12/6)	=EXP(C$3*$A12/6)	=EXP(D$3*$A12/6)	=EXP(E$3*$A12/6)	=EXP(F$3*$A12/6)
10	=EXP(B$3*$A13/6)	=EXP(C$3*$A13/6)	=EXP(D$3*$A13/6)	=EXP(E$3*$A13/6)	=EXP(F$3*$A13/6)
11	=EXP(B$3*$A14/6)	=EXP(C$3*$A14/6)	=EXP(D$3*$A14/6)	=EXP(E$3*$A14/6)	=EXP(F$3*$A14/6)
12	=EXP(B$3*$A15/6)	=EXP(C$3*$A15/6)	=EXP(D$3*$A15/6)	=EXP(E$3*$A15/6)	=EXP(F$3*$A15/6)
13	=EXP(B$3*$A16/6)	=EXP(C$3*$A16/6)	=EXP(D$3*$A16/6)	=EXP(E$3*$A16/6)	=EXP(F$3*$A16/6)
14	=EXP(B$3*$A17/6)	=EXP(C$3*$A17/6)	=EXP(D$3*$A17/6)	=EXP(E$3*$A17/6)	=EXP(F$3*$A17/6)
15	=EXP(B$3*$A18/6)	=EXP(C$3*$A18/6)	=EXP(D$3*$A18/6)	=EXP(E$3*$A18/6)	=EXP(F$3*$A18/6)
16	=EXP(B$3*$A19/6)	=EXP(C$3*$A19/6)	=EXP(D$3*$A19/6)	=EXP(E$3*$A19/6)	=EXP(F$3*$A19/6)
17	=EXP(B$3*$A20/6)	=EXP(C$3*$A20/6)	=EXP(D$3*$A20/6)	=EXP(E$3*$A20/6)	=EXP(F$3*$A20/6)
18	=EXP(B$3*$A21/6)	=EXP(C$3*$A21/6)	=EXP(D$3*$A21/6)	=EXP(E$3*$A21/6)	=EXP(F$3*$A21/6)
19	=EXP(B$3*$A22/6)	=EXP(C$3*$A22/6)	=EXP(D$3*$A22/6)	=EXP(E$3*$A22/6)	=EXP(F$3*$A22/6)
20	=EXP(B$3*$A23/6)	=EXP(C$3*$A23/6)	=EXP(D$3*$A23/6)	=EXP(E$3*$A23/6)	=EXP(F$3*$A23/6)
21	=EXP(B$3*$A24/6)	=EXP(C$3*$A24/6)	=EXP(D$3*$A24/6)	=EXP(E$3*$A24/6)	=EXP(F$3*$A24/6)
22	=EXP(B$3*$A25/6)	=EXP(C$3*$A25/6)	=EXP(D$3*$A25/6)	=EXP(E$3*$A25/6)	=EXP(F$3*$A25/6)
23	=EXP(B$3*$A26/6)	=EXP(C$3*$A26/6)	=EXP(D$3*$A26/6)	=EXP(E$3*$A26/6)	=EXP(F$3*$A26/6)
24	=EXP(B$3*$A27/6)	=EXP(C$3*$A27/6)	=EXP(D$3*$A27/6)	=EXP(E$3*$A27/6)	=EXP(F$3*$A27/6)
25	=EXP(B$3*$A28/6)	=EXP(C$3*$A28/6)	=EXP(D$3*$A28/6)	=EXP(E$3*$A28/6)	=EXP(F$3*$A28/6)
26	=EXP(B$3*$A29/6)	=EXP(C$3*$A29/6)	=EXP(D$3*$A29/6)	=EXP(E$3*$A29/6)	=EXP(F$3*$A29/6)
27	=EXP(B$3*$A30/6)	=EXP(C$3*$A30/6)	=EXP(D$3*$A30/6)	=EXP(E$3*$A30/6)	=EXP(F$3*$A30/6)
28	=EXP(B$3*$A31/6)	=EXP(C$3*$A31/6)	=EXP(D$3*$A31/6)	=EXP(E$3*$A31/6)	=EXP(F$3*$A31/6)
29	=EXP(B$3*$A32/6)	=EXP(C$3*$A32/6)	=EXP(D$3*$A32/6)	=EXP(E$3*$A32/6)	=EXP(F$3*$A32/6)
30	=EXP(B$3*$A33/6)	=EXP(C$3*$A33/6)	=EXP(D$3*$A33/6)	=EXP(E$3*$A33/6)	=EXP(F$3*$A33/6)

I'm taking sensible precautions (as a 60+ year old chap in generally good health) and preparing for a few weeks of quiet life. Keep calm and keep washing your hands!

I don't usually link to facebook, but this post by Abdu Sharkawy who has been a front line doctor in a number of infectious disease outbreaks (SARS, Ebola &c) seems useful.


A basic rye loaf

Jane Eastoe's Bread Making is published by the National Trust and Pavilion books. It is a small format thin hardback with lots of recipes for bread. Line illustrations by Alan Hancocks rather than fancy colour photos. Below is a slightly adapted version of the very simple rye loaf recipe. Actually not so much a loaf as a pudding but that is how rye flour swings...

Method (I'm taking a few liberties here...)

When this one has dried out I'll see how it goes and try a larger version (500g flour in a 1kg tin). Pimping possibilities include: caraway seeds; nuts (choped walnuts, roughly chopped pumkin seeds); dried fruit; honey; treacle

Another similar recipe using light (sifted) rye flour and a bit more salt. Commenter warns that trying to scale up means bread does not cook in middle. Try 1.5x (450g rye and 375g water) and longer cooking time at a lower temperature?

The bog people had a diet of gruel of grains, and this rye pudding comes several steps up from that.

This Way...

FreeBSD on a laptop with xfce

Notes towards a page on using FreeBSD 12.1 on a Thinkpad X220 with 8Gb ram and a 120Gb SSD. Seems solid and responsive. Second iteration: just follow the handbook for Xorg and video drivers with a few tweaks for shutdown and suspend from within xfce4. Use the 2d intel driver for now with xfce4 4.14 as the themes render funny with kms 3d driver enabled.

Automount usb sticks (vFAT) and external hard drives (NTFS)

To do

Gino's pizza

Did a couple of pizzas based on Gennaro Sheffield D'Acampo's basic neopolitan pizza recipe today. Works well and pleasantly moist with about 15 min at gas mark 7 in my old Creda oven.

Variations: mixed 200g of passata with table spoon of olive oil, a crushed and chopped garlic clove and some dried basil (as no fresh) in a bowl and spooned it on. Used a heaped tablespoon of wholemeal spelt in the flour (about 30g or 15%) to add a bit of colour and flavour. Used 1 tsp of Alinson's quick yeast (about 3g) rather than the 7g sachet in the original recipe - left it an hour or so to rise in the bowl before shaping. Loadsa toppings to finish off bits of stuff in the fridge (fried plantin, fried red onion, fried red pepper, wilted spinach, walnuts, about 70g of Feta cheese). Result moist and flavoursome. We ate one pizza and the other one has been halved for snacks tomorrow.

Went down well. Next time: less eclectic toppings - going for passata/garlic and walnut pesto with a strong blue cheese.

Walnut pesto: two bags of fresh basil washed, stalks removed and roughy chopped, 60g of walnuts, loads of olive oil. Grind together using the grinder attachment on my trusty Phillips blender. Should be paste like and strong tasting. Add to spelt penne or wholemeal spirali for main course or use as topping.

Last time we had frost...

Last time we had frost was November - local public art.

We don't get cold winters here these days. When I first moved to Birmingham you could bank on a week or two of frosts and at least a few snow days. Not so much now. David Mamet has written an essay (somewhere) about reading the weather diaries of Vermont farmers and tracking the occurences over the decades of the phrase "The winters were colder then". Can I find it when I need it? Not a chance.

Ordovician Tide

The Ikon Gallery is showing an exhibition by Meryl McMaster: staged self portraits in costumes. Poems (each presented in Plains Cree and in English) explore the Atlantic community and the tension between indigenous and migrant. The Ordovician Tide images, with scrolls in corked bottles being sent on the waves from Newfoundland, struck a chord with the last couple of lines...

"An urgent need to preserve our stories.
Is someone listening in the future?"

Some posters on political fora (e.g. Slugger O'Toole) beginning to explore a North Western identity as a result of the Brexit shambles. Western Isles, western Scotland, Northern Ireland continuing down to Wales coast, through to Cornwall. Cultural connections and common stories as families migrated for work. Things shifting around a bit as identities realign. I feel a need for some North light.

Ciabatta style yeast bread

Same method as my standard yeast bread recipe. Start when you get up and bake early evening. Or leave the poolish overnight and bake mid-morning.


Mix and leave for about 6 to 10 hours or so in kitchen, more in cooler part of house. Will show small bubbles and bran in wholemeal will soften and swell.


Mix to rough dough and leave to autolyse for about 15 to 20 min. Then knead for 10 min or so adjusting the flour/water content as appropriate. If too sticky, knead on generously floured surface. If too stiff, knead with wet hands and 'dimple' in more water by the teaspoon. Cover and leave in oiled bowl for about two hours to more than double in volume, often triple. This is quite a lively dough, will show big bubbles (I use a Pyrex bowl so I can keep an eye on the CO2).

Knock back by folding several times. Shape into rough ciabatta shape and place on well oiled stainless steel tray - perhaps flour bottom - dough will spread. Proofs in about an hour to an hour and a half. Score and bake in oven for around 30 to 35 min. Start highest with steam tray underneath. Reduce to Gas 7 / 200 after 10 min, and for last 10 min turn upside down to cook the bottom. cool on rack.

Enjoy the bubbles with olive oil, vinegar and tomato sauce dips and olives.

Keith Burnett, 2020