home / notes / 2021 / 2020 / 2019 / 2018


Where is the Sun now?

The program below will print the altitude and azimuth of the Sun at the current system time. It is the sequel to the moon.c program included last year's notes.

The program is basically a step by step implementation of the calculation that you will find on page C24 of a copy of the Astronomical Almanac dating from sometime in the last couple of decades. No loops and only one function. I've been very wasteful of multiplications (repeated conversions of arguments to and from radians for instance) and calls to sine and cosine.

/* cc sun.c -lm -o sun */
/* altitude and azimuth of Sun *now* on a Unix-like OS 
   method based on page C24 in a recent Astronomical Almanac 
   or the Explanatory Suppliment */

#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.1415927

double range(double y);

int main(void) {

time_t now;
double d, t, L, g, lambda;
double epsilon, y, x, alpha, delta;
double lst, ha, alt, az;

/*  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");
    }
    d = (now - J2000)/(86400.0); /* days since J2000.0 */
    /* d = -877.04167; test from Meeus */
    L = range(280.461 + 0.9856474 * d);
    g = range(357.528 + 0.9856003 * d);
    lambda = range(L + 1.915 * sin(g*RADS) + 0.020 * sin(2*g*RADS));
    epsilon = 23.439 - 0.0000004 * d;
    y = cos(epsilon*RADS) * sin(lambda*RADS);
    x = cos(lambda*RADS);
    alpha = atan2(y , x);
    delta = asin(sin(epsilon*RADS)*sin(lambda*RADS));
    lst = range(280.46061837 + 360.98564736629 * d + LONG);
    ha = range(lst - alpha*DEGS);
    alt = asin(sin(delta) * sin(LAT*RADS) + cos(delta) * cos(LAT*RADS) * cos(ha*RADS));
    printf(" alt: %3.0f\n", alt*DEGS);
    y = -cos(delta) * cos(LAT*RADS) * sin(ha*RADS);
    x = sin(delta) - sin(LAT*RADS) * sin(alt);
    az = range(atan2(y, x)*DEGS);
    printf("  az: %3.0f\n", az);
}

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

Reduce bandwidth

Linking to the images rather than using the image tag on this page reduces the initial page load by a huge percentage, from 2.94Mb to 160Kb. My old phone is happier, as are my half dozen readers. When I edited this page and the notes 2020 page, I found that I was adding more context to the image links, so the writing may improve as well.

Have a look at What does my site cost. It is fair to mention that many questioned the costings on the associated HN discussion, but the file size estimate is accurate. The underlying Web Page Test report gives this site a failing score for security. That is surprising as I'm not using any javascript or scripting of any kind, and the page is served using https. One to look at.


Drawing a segment in OpenOffice

Segment of a circle drawn in Apache Open Office Impress.

There are a lot of shape facts in the foundation tier of GCSE Maths. Like the shallow end of the swimming bath, it is wide but not very deep, a scatter-gun coverage of a huge range of material.

I'm knocking off a couple of slides each day with diagrams and minimal text captions. Any attempt at a connected narrative would probably overwhelm adult education students, and besides, any future narrative will need diagrams so no effort now will be wasted.

Above is my sketch of a segment of a circle. If you think about segments of an orange, you'll see why students get segments and sectors mixed up. How did I draw this using the tools in Apache OpenOffice Impress? Basically recapitulating the method for calculating the area of a segment (calculate area of the sector, then of the isosceles triangle with base AB and then subtract). I made use of the align functions as well to centre the circle, the sector and the isosceles triangle objects. The edit points function was handy with the triangle after converting it to a polygon.

The slight pinch on the right hand of the outer circle in the png file above is an artifact of the export selection function in OpenOffice. The boundaries of the selected object are drawn very tightly and seem to ignore the line width setting.


Heirloom Vi - xvi

The posix standard includes the vi editor, so you will find a vi command of some kind on just about any *nix or Linux operating system.

Most Linux distributions use the vim minimal configuration for Vim. OpenBSD uses nvi by default, as does Slackware depending on the choices you make at installation. These fine programs give the user some slack (sic) by enabling the cursor arrow keys and the backspace/delete keys.

The xvi editor is a portable editor based on stevie. Installing using the instructions in INSTALL and doc/README for the -p or posix variant results in the full hair shirt 300 baud vi experience. Backspace does not work, pressing the backspace key results in the insertion of the control code \\214 at the cursor position when in insert mode. Similarily, attempting to use the arrow keys to move the text insertion point around results in any of \\206, \\204, \\207, \\205.

Deeply frustrating for casual use - for instance hunt and pecking this note out. But the annoyances make you learn quicker. Movement commands in command mode become very important and readily to hand.

By default, xvi is installed into /usr/local and I found it necessary to symlink the man page thus...

ln -s /usr/local/share/man/man1/xvi.1 /usr/man/man1/

I should perhaps have changed the install path to something more usual for Slackware.


100% wholemeal sourdough

Close up photo of dough showing strands of gluten and bubbles.

Marks and Spencer's Strong Wholemeal Flour Dough (in the mid-brown bag with white writing) produces a reasonable sourdough. The recipe on the side of the pack suggests 500g flour with 350g of water - which is higher than usual for supermarket flours. That coupled with the 'manufactured in UK with wheat from more than one country' disclosure and the English/French nutrition text leads me to suspect that there may be some French flour in the bag. In the UK, the bread flour regulations do not require the usual additives for 100% wholemeal flour, so no chalk added so best not used as daily bread.

I used my modification of Emmanuel Hadjiandreou's wholemeal sourdough recipe with half a teaspoon of salt, some rosemary seeds and a shake or so of ground cinnamon. The resulting dough shows plenty of strandy gluten as shown in the photo. It still spreads on the oven tray while proofing though so you don't get a tall boule from this dough. Plenty of mid-sized holes though.

Not bad for about 40p worth of ingredients and 18 hours clock time (half an hour prep or perhaps 45 minutes).


Metapost and plain TeX on Slackware 14.1

Xpdf displaying the output from pdftex with a metapost graphic

A quick metapost example works fine with the ancient tetex version 3.0 that is installed by default on versions of Slackware prior to the current pre-15.0 beta.

Save the metapost commands below in file.mp...

beginfig(1);
z1=(0,0);
z2=(10mm,10mm);
drawarrow(z1--z2);
label.ulft(btex $A$ etex, .5[z1,z2]);
endfig;
bye

Then save the TeX source below in file.tex...

\input ifpdf.sty
\ifpdf
  \input supp-pdf
  \def\epsfbox#1{\hbox{\convertMPtoPDF{#1}{1}{1}}}
\else
  \input epsf
\fi
Hi there:  \epsfbox{file.1}
\bye

Then process the metapost file and then the tex file using...

$ mpost file.mp
$ pdftex file.tex

The image at the top of this note shows what file.pdf looks like in xpdf. The first 7 lines of the TeX file are loading a package and a macro that convert the eps files produced by metapost to pdf so that they can be included in the output from TeX. Inline use of metapost code in the TeX file may not be possible in TeTeX - I'm digging through Web pages from the early oughties to find out.

The mpost command creates files with names like file.1 which contain eps markup but which are not complete eps files. Metapost can't insert any text into the pictures itself, it relies on TeX to generate the labels - see the btex $A$ etex fragment of file.mp.

The example file from the metapost Wikipedia page works fine. That shows how to have several diagrams in one metapost file.


Lyx on Slackware 14.1

Slackware64 14.1 install on 60Gb SSD on the Atheros X61s with kernel packages from 14.2 /patches. I'm also using Seamonkey 2.53.7.1 binaries from the Seamonkey project site - unpack, mv to /opt/seamonkey and set paths and preferences. Along with Apache OpenOffice you get a very usable desktop.

Lyx from slackbuilds provides a WYSIWYW interface for writing - it is limited by the TeX backend, in the case of Slackware prior to 15.0/current that was basic as provided by TeTeX.

Native TeX is provided by TeTeX which is, as mentioned, old...

bash-4.2$ tex --version
TeX 3.141592 (Web2C 7.5.4)
kpathsea version 3.5.4
Copyright (C) 1997-2004 D.E. Knuth.
Kpathsea is copyright (C) 1997-2004 Free Software Foundation, Inc.
There is NO warranty.  Redistribution of this software is
covered by the terms of both the TeX copyright and
the GNU General Public License.
For more information about these matters, see the files
named COPYING and the TeX source.
Primary author of TeX: D.E. Knuth.
Kpathsea written by Karl Berry and others.

So when compiling Lyx against this, you will end up with poor quality fonts in Lyx 2.1.4 from slackbuilds. This is strange, as TeX and LaTeX give fine sharp fonts. The work around is in Lyx go to the Documents | Settings | LaTeX Preamble textbox and add this...

% set fonts for nicer pdf view
\IfFileExists{lmodern.sty}{\usepackage{lmodern}}{}

then Apply and restart Lyx. Processing with the pdfLaTeX command within Lyx should give nice sharp fonts.


Appliances and integration

A blog post by Protesilaos Stavrou got me thinking a little bit about how I relate to software in general - about my understanding of my computing if you like. As a pragmatic Brit I tend not to philosophise too much about these things, but sometimes it is good to render the invisible a little bit visible.

As a child of the 1950s/1960s I can remember learning to use the radio, and the television. Also the record player (trying not to scratch Dad's records). I was allowed to use the camera now and again and watched my father develop the resulting transparancies in the grey tank with the purple solutions with some awe. Mum's typewriter (a huge Olympia) provided some finger exercise. Enough reminiscing, you get the picture, I grew up with appliances. Machines that were designed to fulfil one function and whose structure (despite the 1960s styling) tended to reflect that function.

So I got used to thinking about taking pictures as one discrete activity, typing stuff as another and listening to Radio Caroline as a third. The first personal computer that I had (shared) access to had two floppy disk drives, one for the program and one for your data. You had to change the disk to change the program. The machine itself no longer reflected its function but the physical process of swapping the system disk underlined the change in mode of the machine.

All of this experience over decades reinforced my tendency to think in discrete activities. So I find using one program to word process, another to manage photographs and a third to browse the Web perfectly normal and to be expected. I'm used to thinking in a camera way when using a camera, and thinking in a reading way when browsing the Web. The idea of using a different language or configuration for those activities is nothing special. I suspect that was the general experience of the Unix programmers originally, they are a generation ahead of me so their pre-PC experience must be a couple of decades longer on average.

At the moment therefore, emacs is a light weight IDE to me. I'll see if it spreads its rhizomes any further into my computing.


Lex Fridman interviews Charles Isbell

Video #135 on Lex Fridman's podcast takes the form of a leisurely structured interview with Charles Isbell of the Georgia College of Computing.

Asked about computer education for everyone, Dr Isbell shared the following thoughts (1h 29min into the video and I've paraphrased somewhat so not exact quotes, and the fast flowing dialogue has been somewhat condensed and punctuated which is my arbitrary choice)...

"Everyone needs to learn how to think in the way that you can be precise, and by precise I mean in a way that is reproducible... Saying what it is that you want the machine to do... Describe the problem in such a way that it is executable (which human beings are not good at)... surfacing assumptions"

The whole video (all two and a quarter hours) was interesting - it is nice to see an interviewer themselves a domain expert exploring a subject with a leader in the field - but that quote stood out to me. We perhaps don't need mass downloads of Anaconda and Python for Primary, but a renewed focus on precise description of a procedure. That description could of course be tested by implementing it in some suitable language on a generally available machine.


Incremental backups with tar

Most of my working files are either text or images/packages. Text files take very little disk space. Images, sound recordings and packages such as .txz or .odt files are already compressed. Using tar without compression makes a lot of sense to me. I can save the .tar files to NTFS formatted external hard drives and preserve my Linux permissions. If one or two blocks go bad (never happened... yet) I can still restore the rest of the `.tar' file.

To back up ~/Documents/project I just use a script like this from the ~/Backups directory...

[19:10]~/Backups$ cat project-backup.sh
#
# Creates incremental backups of Documents/project directory
# use tar -xopf to unpack earliest tar file first for a
# full restore
#
tar --create \
           --file ~/Backups/project.$(date +%Y%m%d-%H%M%S).tar \
           --listed-incremental ~/Backups/project.snar \
           ~/Documents/project

I suppose I ought to use a variable to store the project directory name - perhaps itself an argument to the script. This script fragment started as a command line and got packaged into a file for convenience.


Suddenly we were confronted by...

Scene of crime photograph

...a 12 foot high photocopy of Pat Butcher off Eastenders pasted onto the wall of a viaduct in Digbeth.

The only question can be: why?


A three hour loaf

Morrison's are now stocking their own brand brown flour at a sensible price. In need of a quick loaf, I used the recipe on the back without the olive oil, less salt and half the yeast. The result rose OK and is tasty with my usual addition of a couple of shakes of rosemary seeds.

The method is pretty standard...

A previous loaf using this flour with a sourdough starter, poolish and long ferment resulted in a very sticky dough and a crumb that looked like pumpernickel. I noticed the ingredients include 'flour agent' (alpha-amylaze) and I suppose that this flour has been formulated for quick rise recipes.


Wallpaper: Blossom against sky

Boughs of a white decorative cherry tree showing blossom against the sky


Script to convert a markdown file to a complete Web page

Suppose you have a directory md with text files in markdown format, and another directory html. Run page.sh md/some-page.md and the script will run the markdown formatted text of md/some-page.md through the markdown command, add a header and footer to the resulting html and save the lot to md/some-page.html in the html directory.

#!/bin/bash
#
# File name in first argument
#
FLNMSTM=$(basename  $1 .md)
#
# Fetch the title of the page
#
NOTETITLE=`grep -B 1 '^=====' $1 | head -n 1`
#
# run markdown on the file
#
NOTEBODY=`markdown $1`
#
# print the page header
#
cat <<EOF > html/$FLNMSTM.html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
$NOTETITLE
</title>
<style type="text/css">
body {margin: auto;font-family:"Verdana", sans;
font-size: 125%;line-height:150%; max-width: 720px;}
h1, h2, h3, h4 {line-height:120%}
pre {line-height:120%;}
</style>
</head>
<body bgcolor="#ffffff">
<p><a href="../index.html">home</a> / about </p>
EOF
#
# print the previously converted body copy
#
cat <<EOF >> html/$FLNMSTM.html
$NOTEBODY
EOF
#
# print the footer
#
DATENOW=`date +"%A, %e %B %Y"`
cat <<EOF >> html/$FLNMSTM.html
<hr />
<p><small>Last modified: $DATENOW 
| <a href="https://justinjackson.ca/words.html">
This is a Web page</a></small></p>
</body>
</html>
EOF

I'm using the Markdown.pl command as downloaded from Daringfireball. The script is renamed to markdown and parked in ~/bin which is in the path. I've decided that each md file must have exactly one level 1 heading that will become the title of the Web page. That level 1 heading must use the ===== on the line underneath style. You can have some lines above the level 1 heading.

This is all a work in progress. You are looking at a couple of hours of copy and paste from various Web sites (Stackexchange and all). I'll make it less bash centric and more robust over time. A script to generate an index page is coming along...


Concrete ensos

circular mark on a concrete wall and a grid set into textured concrete


The Noguchi Yukio filing system

Your file manager can already implement the Noguchi filing system

Professor Noguchi was, so the story goes, having problems with paperwork. So he just put everything in a box and always put the most recent thing he was working on at the front of the box. After a time, he noticed that the folders sorted themselves into an order so that the things he had to work on most often were at the front, and old finished folders migrated to the back of the box.

The formalised version seems to work like this...

Divide the stream of paper up into coherent groups somehow, e.g. a task or an order (suppliers, costs, purchase order form, copy of actual order, guarantee and so on).

Artifacts for each group go in an envelope modified so that the papers are visible at the top - cutting off the flap and an inch or so of the envelope seems to be popular. I fancy getting some of those orange internal mail envelopes with the holes in and the string/card closures.

Some metadata is written on the outside - date started, things needed, title and so on. The envelopes are stored on a shelf. Newest envelope on left, older ones on right.

Once there are a good supply of envelopes, you just

Over time, the things that are worked on most recently will tend to be found on the left of the shelf. Those envelopes on the right will gather dust slowly and can be archived eventually.

I imagine there will be tricky cases: perhaps an old envelope will need to be consulted to answer a single isolated question; an envelope for a project will become very full as the project develops. Judgement will be needed about when to return the envelope to the extreme left, and when to split (or combine) envelopes.

Implementing this system for a series of files or directories is automatic, the operating system will record the time when the file or directory was last modified. Most graphical file managers have an option to list files in date order by modification date, with most recent files or directories on the top of the list.

At the linux command line just use...

$ ls -lt | cut -c 36- # The 36- depends on length of your user name

and the names of the files/directories will be listed in date order preceded by the date.

When doing backups, you will need to preserve the file attributes (e.g. rsync -av... as otherwise the file time stamps will change when you copy the tree. If you are backing up to a VFAT or NTFS disc or usb stick, it will be best to use a tar file so as to preserve the file attributes.


Slackware: DrRacket

A picture of Dr Racket scheme IDE running a two line check.

Just follow the instructions to download and install the 64 bit sh file. DrRacket provides an IDE with trace and debugging and lets you save a record of the session and save any functions you defined in a separate file. Having installed the SICP language package, I can work through the classic programming challenge at my leisure.

Slackware comes with three lisps: elisp in emacs; guile and clisp. I've added a fourth as it comes with the IDE that allows bottom-up programming in a way I recollect from LOGO.


Slackware: Audacity 3.0 on current

AlienBob has provided a slackbuild of the newly released Audacity 3.0. Version 3 uses a new storage system for 'projects' using the SQLite3 database to store both binary and the audacity audio commands. There are some dependencies to add to a default Slackware current install. I saved the URLs of all the needed binaries in packages64.txt as follows...

http://slackware.uk/people/alien/slackbuilds/audacity/pkg64/current/audacity-3.0.0-x86_64-1alien.txz
http://slackware.uk/people/alien/slackbuilds/jack2/pkg64/current/jack2-1.9.16-x86_64-1alien.txz
http://slackware.uk/people/alien/slackbuilds/ladspa_sdk/pkg64/current/ladspa_sdk-1.15-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/lilv/pkg64/current/lilv-0.24.10-x86_64-1alien.txz
http://slackware.uk/people/alien/slackbuilds/serd/pkg64/current/serd-0.30.0-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/sord/pkg64/current/sord-0.16.2-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/sratom/pkg64/current/sratom-0.6.2-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/soxr/pkg64/current/soxr-0.1.3-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/suil/pkg64/current/suil-0.10.2-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/lv2/pkg64/current/lv2-1.18.0-x86_64-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/vamp-plugin-sdk/pkg64/current/vamp-plugin-sdk-2.8.0-x86_64-2alien.tgz

Making a directory (say audacity3) and running...

$ wget -c -i packages64.txt

...should fetch all the packages. Opus is listed as a dependency of Jack2 but appears to be part of a default Slackware current installation.

The 32 bit packages have some variation in the naming convention, so packages.txt looks like this...

http://slackware.uk/people/alien/slackbuilds/audacity/pkg/current/audacity-3.0.0-i686-1alien.txz
http://slackware.uk/people/alien/slackbuilds/jack2/pkg/current/jack2-1.9.16-i586-1alien.txz
http://slackware.uk/people/alien/slackbuilds/ladspa_sdk/pkg/current/ladspa_sdk-1.15-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/lilv/pkg/current/lilv-0.24.10-i586-1alien.txz
http://slackware.uk/people/alien/slackbuilds/serd/pkg/current/serd-0.30.0-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/sord/pkg/current/sord-0.16.2-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/sratom/pkg/current/sratom-0.6.2-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/soxr/pkg/current/soxr-0.1.3-i686-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/suil/pkg/current/suil-0.10.2-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/lv2/pkg/current/lv2-1.18.0-i586-1alien.tgz
http://slackware.uk/people/alien/slackbuilds/vamp-plugin-sdk/pkg/current/vamp-plugin-sdk-2.8.0-i586-2alien.tgz

The resulting program works fine and seems slightly more responsive. The few features I use (fade in, fade out, rough cutting out of bits of dialogue, some use of amplification and bandpass filter and perhaps a bit of compression) seem to work just the same. Because of the format change, 'projects' opened in Audacity 3 and saved in the new format cannot be opened in Audacity 2.x so copy the 'project' folder if you think you might want to go back to Audacity version 2.x

Jouni Helminen joined the HN discussion of the Audacity 3.0 release announcement to say that he is working with the Audacity team on a redesign of the UI/UX. He will no doubt be getting plenty of suggestions (which will of course contradict each other). I'm sure the quote below will be printed and pinned up above the monitors...

"One goal is that its user interface should be discoverable: people should be able to sit down without a manual and start using it right away, gradually discovering its features. This principle has been crucial in giving Audacity greater consistency to the user interface than there otherwise would be. For a project in which many people have a hand this kind of unifying principle is more important than it might seem at first."
-James Crook in The Architecture of Open Source Applications

Wallpaper: bifurcation

Pebble river bed in the new path where Pebble Mill used to be


224,996

Booked my slots Tuesday after the letter arrived in the morning post. I was one of 224,996 people to receive their first dose of the COVID vaccine yesterday, a fact that I find strangely democratic.

Arrived at Millennium Point at 25 past (appointment for half past). Presented letter, gave date of birth, sat within a grid of chairs for 10 to 20 minutes or so. Invited to trundle off to the next grid of chairs. The queue manager was impressively working from spatial memory, no raffle tickets. Presented the same information, plus postcode and next of kin. Sat for another 10 to 20 min or so. Called to a third stage, the lanes, where the actual injections took place. Asked for the same information, plus confirming my GP name and location and providing a contact number and choosing an ethnic self-description. Appraised of possible side effects, got injected (painless, much thinner needle than the 'flu jab chisel a month ago). Presented with my card, sticker and side effects leaflet. Then out (via loo).

Was in there for 1h 15 min. Well organised. 60 or so people at each stage, refreshing every 10 mins. Pretty large scale and slick. Nice feeling, even though this was the largest number of people that I have been in an enclosed space with for just under a year. The atrium is a three story high space the size of a football pitch with some to spare.

Booking Web site was reassuringly minimal, no fancy responsive design, should work on any device, which I think is a very good idea. A series of steps with one question each step. When offered a list of time slots, choose a middle slot not the first. Otherwise you reach the end to be told that there is a problem with one of the appointments because someone else got that first slot before you did. Again, a strangely democratic feeling: thousands of people out there booking.

Some numbers: 225000/32 slots = about 7000 people per 15 min slot nationally, which is about 450 per minute on average. That's the way to do it.

No side effects at all, not even a sore arm. Same with the 'flu vaccination in January (my first, motivated by request by letter).

I have many questions about how a rich and powerful country with universal health care clocked up such a huge death toll, 30+% of that as late as January. But the vaccination process was deeply reassuring, public sector mass provision at its best.


Wallpaper: spray can test

Colour test with spray paint

The walls of the subway underneath gravelly hill interchange where taggers have been testing out their spray paints. A bit of sun makes such a difference! I used the Transform | Rotate tool in GIMP 2.8 to rotate the image (before cropping and scaling down) to correct a slant in the tiles.


Generate secure passwords: multiline alias in bashrc

You do not want to be that intern. Avoid this ignominious fate by using a handy bash pipeline...

alias genpass="head -c 2000 /dev/urandom | \
tr -dc 'a-zA-Z£\@\$' | \
fold -w 12 | head -n 20"

Adding the above multiline alias to your .bashrc will, when sourced, result in the following typical output...

bash-4.3$ genpass
Hcl�WRHmq6Nn
RgaivLBRM34M
v7ibbIG2oHd0
06y9wB1KuzK3
NUWkTsX3fmIc
emP1lr7e4J0W
1r1TmGZmOdjD
0cHk0EXpPM2o
GPpqURhYTXwg
M3pLrCrINhk�
HsCmaL90hZ3h
jn93hE6TN6EE
PRrIMEWc7y�4
HL8�pU5djF82
44aEPVotMXkm
WI7�B96Txj8j
zECX$t3NAsWq
tTsrztN3O$Ck
7dwiR@l3MqR�
Os$smwR6N9$0

A choice of 20 passwords each of 12 characters. The character set can include upper and lower case letters, numbers, and the special characters @, £ and $. That is 65 possibilities for each character.

The chances are that at least one of the 20 passwords will comply with your corporate password policy. In which case you write it down in your little black password book and use it for the three weeks that passwords last before the (brain dead) System makes you pick a new one.

The /dev/urandom command returns 2000 (reasonably - see man urandom) random bytes, however these bytes may include all values and so we need to filter them so as to produce things you can actually type on your keyboard. To do this, we pipe the output into the tr command which translates the bytes into lower case, uppercase and numeric characters, plus the three 'special' characters @, £ and $. Because the @ and $ characters have a meaning when applied to regular expressions, and thus alter the way that tr works, you have to escape them by using the \ character. That same \ character can be used between commands to break the line into smaller sections. Note that the \ characters have to be within a command and so just after the pipe (|) characters.

Then we pipe the filtered characters into the fold command that chops them up into sets of 12 characters per line. You can (of course) alter the number of characters per line by changing the argument. Finally, the lines are piped into head to select just the first 20 lines. Again, you can have more or less lines by changing the value of the argument. I wanted to make sure that I would end up with at least one password that would satisfy the complexity requirements.

So how secure is a password derived from 12 'random' picks from 65 characters? Well my1login thinks that these are pretty secure. 'Time to crack your password: 26 billion years' for tTsrztN3O$Ck, but then the time to crack is only 23 thousand years for RgaivLBRM34M. Pretty logarithmic variation (which is to be expected as it is information content or entropy that we are talking about).

The Kaspersky password checker estimates that a home computer would take 4 centuries to crack tTsrztN3O$Ck but also for RgaivLBRM34M (so much for special characters!).

The Rumkin password checker gives me an estimate of the entropy for each password. Good old tTsrztN3O$Ck yields 61.6 bits of entropy but thinks that it is chosen from a 72 character set. RgaivLBRM34M yields 57.5 bits of entropy from an estimated 62 character set. Special characters are good here!

Mr Pleacher provides the formula for calculating the entropy of a password as E = log2(RL) (same as E = ln(RL) / ln(2)) where E is the entropy in bits, R is the number of unique characters in the password (65 here) and L is the number of characters in the password (12 here). Cranking the handle on that lot gives around 72 bits of entropy (try the calculation in WolframAlpha).

head -c 20000 /dev/urandom | \
tr -dc 'a-zA-Z£\@\$' | \
fold -w 12 | \
head -n 300 | \
fmt > pin-this-up-on-your-noticeboard.txt

The command above will generate 300 passwords each of 12 characters so you can print them out and hide them under the keyboard. Seriously, you need to generate many more bytes from urandom than you want printed as the tr filter will reject bytes that don't match the reg exp.


Wallpaper: scarborough

Scarborough sky looking out from North Bay

October 2019 looking out to sea.


'Roman' flatbread

Flatbread: in the pan and what it looks like when cooked.

Soft and chewey, these flatbreads are easy to make and mop up sauces nicely. The ones shown here used a yeast based sponge, and about 20% wholemeal bread flour and 80% white bread flour. I'm planning to use a sourdough for the sponge and 50% wholemeal spelt flour for a more authentic flavour next time.

This recipe is adapted from an Atlas Obscura page that reconstructs a pub meal in Pompeii, complete with duck boiled in broth and a 'portable' brazier. I use less yeast and a longer rise time (I'm always worried about making sure the yeast is killed in the cooking process, which is very short for pan bread) and less salt than the original recipe.

The modified recipe makes two flatbreads each about 6 inches across and an inch thick. I didn't think to weigh them!

Sponge

Add yeast to the water and rest for 5 minutes to start bubbling. Add yeast/water to flour in a small bowl and mix to smooth batter. Cover and leave to stand for a couple of hours. Should have risen a bit and be bubbly.

You can use 60g of an active sourdough starter instead of this sponge.

Dough

Shaping and cooking

I'm thinking about seeds and nuts added to the dough and about cooking on a stone in the oven with a few toppings. Romans sometimes made cheese and herb dips for their bread. The bread was not always leavened, and not always wheat flour.

On the stone

Flatbread cooked on a stone, fold side up (twilight).

Re-visited this recipe today, complete with yeast based sponge, and with 125g of wholemeal spelt and 125g of bog-standard white bread flour (plus the 30g from the sponge). Cooked on a pizza stone at the top of the oven for roughly 12 to 14 min. Above photo taken in twilight so a bit of a blue tinge. Better rise, and slightly more crisp on the outside. Still chewey and reasonably moist.

Next time, I'm just going to have to do one on the stone and the other in a pan to compare. I have a suspicion that I am rediscovering foccacia step by step...


Viewport

Add the line below in the head of a simple html based Web page...

<meta name="viewport" 
content="width=device-width, 
initial-scale=1.0">

...and your work is readable on mobile devices with basic Web browsers and small screens. The viewport tag is the key.


Unknown unknowns...

...are the ones that get you.

"Reports that say that something hasn't happened are always interesting to me, because as we know, there are known knowns; there are things we know we know. We also know there are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns - the ones we don't know we don't know".

Donald Rumsfeld's famous paragraph of spoken prose attracted mirth and hilarity when it was first heard. It has stood the test of time has it not, as long as we add the unknown knowns (or the knowns we cannot see because of our assumptions)?


Wallpaper: winter trees

Bright cloudy sky and crisp (1366x768). I really like the mist on the town centre buildings - bit of recession in the image.


Quotes for the day

The founders had thought about this one, in the context of the risk of a president trying to become a king. Below from an article in The Dispatch, a right wing American publication. Via the often hilarious and occasionally informative Political Betting.

"The truth unquestionably is, that the only path to a subversion of the republican system of the Country is, by flattering the prejudices of the people, and exciting their jealousies and apprehensions, to throw affairs into confusion, and bring on civil commotion. Tired at length of anarchy, or want of government, they may take shelter in the arms of monarchy for repose and security."

"When a man unprincipled in private life desperate in his fortune, bold in his temper, possessed of considerable talents, having the advantage of military habits - despotic in his ordinary demeanour - known to have scoffed in private at the principles of liberty - when such a man is seen to mount the hobby horse of popularity - to join in the cry of danger to liberty - to take every opportunity of embarrassing the General Government & bringing it under suspicion - to flatter and fall in with all the non sense of the zealots of the day - It may justly be suspected that his object is to throw things into confusion that he may 'ride the storm and direct the whirlwind'."
Letter to George Washington, 18th August 1872, Alexander Hamilton, founder.

In other words, people like simple ideas and strong leaders - or so they think until the penny drops.

"Democracy is a system in which parties lose elections"
Democracy and the market: Political and economic reforms in Eastern Europe and Latin America by Adam Przeworski

I like this definition. Nice and short. Brings in the idea of continuity and a container for the political process which as an older chap I approve of. Links to politics as an example of an infinite game.


Cheap premises and studios needed

Whites Ironmongery shop door shutter. The Grotesk font looks really good, varying the sizes to fit the space.

The shutter belongs to a fairly substantial building with a ground floor showroom and upstairs offices on a corner site just over the main road from the Jewellery Quarter. The windows used to display a variety of ironmongery and industrial parts - I noticed the display changed quite often. Now appears to be empty. Pre-COVID the word in my local barbers was that the building changed hands for a significant sum. The (alleged) new owner does not appear to have cleared the space and has not made the future use of the building apparent in any way. The business continues operating from an industrial unit further out of the city centre in an industrial estate with good access for white van drivers.

As I trundle around the Inner Ring for my daily exercise walk, I'm seeing lot of disused small low rise buildings from the immediate post war rebuilding. Many of these buildings are empty and look to have been empty for some time. They do not aspire to any great architectural merit. I'm hoping that they don't all get cleared for mega 'luxury flat' developments (casting their huge shadows over the streets that remain), and that rents can reflect supply and demand instead of booked asset valuations.

It seems that artists and marginal innovators operating outside of the usual academic or business institutions need cheap space relatively near services. The resulting mix is better for density and employment. This is going to be important when we climb out of the COVID deep freeze, there must be little friction for small new businesses to open.


Octave: end user programming for industrial types

subplots from octave 4.4 gui for a damped spring ode

Octave 4.4.1 dating from 2018 is the version in Debian Buster, 6.1 has just been released. I'm working with 4.4.1 for now. Found a useful page with short form code and plots for a range of differential equation based models.

The image above shows the time evolution and phase space for an undriven damped mass on a spring - the 'hello world' of computational physics. The octave code to produce the plots is...

%Save the following contents in a .m file and run the .m file
m = 1;
k = 1;
c = 0.3;
dy_dt = @(t,y) [y(2);...
       -(c/m) * y(2) - (k/m) * y(1) ];
odeopt = odeset ('RelTol', 0.00001, 'AbsTol', 0.00001,'InitialStep',0.5,'MaxStep',0.5);
[t,y] = ode45(dy_dt,[0 25], [0.0 1.0],odeopt);
subplot(1,2,1);plot(t,y(:,1),'r-',t,y(:,2),'b-');
xlabel('time'); ylim([-1.2 1.2]); 
legend('y1(t)','y2(t)');
subplot(1,2,2);
plot(y(:,1),y(:,2),'b-'); 
xlabel('y(2)');
ylabel('y(1)');
xlim([-1.2 1.2]); 
ylim([-1.2 1.2]);

My next move is to work through these various code listings line by line and refer back to the octave manual for the syntax. In particular, the construct that defines the second order differential equation...

dy_dt = @(t,y) [y(2);...
       -(c/m) * y(2) - (k/m) * y(1) ];

...appears to be using the semi-colon, ellipsis and line break in a specific way.

New year's resolution: stick to octave and R and produce some stuff.


New Year sourdough

Sourdough boule sitting in basket for final proof.

Gilchester's Organics half and half wholemeal/white flour, 70% hydration and about 8% starter (40g on 500g of flour). Mixed on New Year's Eve and left overnight to rise. Proof around 1pm New Year's Day. Baked around 3pm. Tasty and dark colour, not a huge rise but some good chewey bread.


Taking advantage of the circumstances

Moss growing on a brick walled warehouse near broken gutter

An old warehouse wall is about 100 feet long and most of it is dry and moss free. A broken piece of gutter where it joins the down pipe is providing a source of water for a vertical moss plantation and a few hardy small plants (recent arrivals). Once the water is flowing the seeds/spores can anchor and start growing. The seeds/spores are widely distributed everywhere but most presumably can't get enough water or light to start growing.

The warehouse has been empty or not much used since the Millennium. One day, a new tennant could come along and have the gutter repaired - a minor job involving a scaffold and perhaps a days work. The mosses would dry out and remain viable as spores for some time. The little plants would die off as a result of their environment changing.


New year...

Bunch of daffs showing blooms this morning

...and I hope new blooms.


Keith Burnett, 2021