Automatically filling in the UK COVID test results page with Selenium IDE

Andy Balaam from Andy Balaam's Blog

Lots of people are filling in the extremely detailed UK government COVID test result page twice every week.

It asks you to fill in a very large list of details, most of which are the same every time, but it doesn’t remember what you typed last time.

I didn’t want to write a Python script or similar to enter my results, because I wanted to check I’d done it right, and because there is a captcha at the end that is clearly intended to prevent automation like that.

However, with a Selenium IDE script, I can drive my browser, watching what it does and checking the input, and manually filling in the captcha and final double-check page.

In case it’s helpful, here is the script I created: report-covid-test.side.

You can create one for each child if you have several, filling in school name, NHS number, names, date of birth etc. in the script and re-using it, modifying it each time to enter the bar code number for the test itself.

To use it you’ll need the Selenium IDE plugin for firefox, or Selenium IDE plugin for another browser.

I’d recommend loading this script into the Selenium IDE plugin in Firefox, looking through it and editing the values that say “ENTER…HERE”, then clicking Run Script and watching it fill in values.

It doesn’t actually submit the result, so you can always check and modify it manually if something doesn’t work out, before clicking the last couple of buttons to submit.

The aura of software quality

Derek Jones from The Shape of Code

Bad money drives out good money, is a financial adage. The corresponding research adage might be “research hyperbole incentivizes more hyperbole”.

Software quality appears to be the most commonly studied problem in software engineering. The reason for this is that use of the term software quality imbues what is said with an aura of relevance; all that is needed is a willingness to assert that some measured attribute is a metric for software quality.

Using the term “software quality” to appear relevant is not limited to researchers; consultants, tool vendors and marketers are equally willing to attach “software quality” to whatever they are selling.

When reading a research paper, I usually hit the delete button as soon as the authors start talking about software quality. I get very irritated when what looks like an interesting paper starts spewing “software quality” nonsense.

The paper: A Family of Experiments on Test-Driven Development commits the ‘crime’ of framing what looks like an interesting experiment in terms of software quality. Because it looked interesting, and the data was available, I endured 12 pages of software quality marketing nonsense to find out how the authors had defined this term (the percentage of tests passed), and get to the point where I could start learning about the experiments.

While the experiments were interesting, a multi-site effort and just the kind of thing others should be doing, the results were hardly earth-shattering (the experimental setup was dictated by the practicalities of obtaining the data). I understand why the authors felt the need for some hyperbole (but 12-pages). I hope they continue with this work (with less hyperbole).

Anybody skimming the software engineering research literature will be dazed by the number and range of factors appearing to play a major role in software quality. Once they realize that “software quality” is actually a meaningless marketing term, they are back to knowing nothing. Every paper has to be read to figure out what definition is being used for “software quality”; reading a paper’s abstract does not provide the needed information. This is a nightmare for anybody seeking some understanding of what is known about software engineering.

When writing my evidence-based software engineering book I was very careful to stay away from the term “software quality” (one paper on perceptions of software product quality is discussed, and there are around 35 occurrences of the word “quality”).

People in industry are very interested in software quality, and sometimes they have the confusing experience of talking to me about it. My first response, on being asked about software quality, is to ask what the questioner means by software quality. After letting them fumble around for 10 seconds or so, trying to articulate an answer, I offer several possibilities (which they are often not happy with). Then I explain how “software quality” is a meaningless marketing term. This leaves them confused and unhappy. People have a yearning for software quality which makes them easy prey for the snake-oil salesmen.

Visual Lint 8.0 has been released

Products, the Universe and Everything from Products, the Universe and Everything

The first public build of Visual Lint 8.0 has just been uploaded to our website. As of today, Visual Lint 8.0 replaces Visual Lint 7.0 as the current supported Visual Lint version.

As such Visual Lint 8.0 licences (as well as upgrades for Visual Lint 6.x and 7.x* per user licences) will shortly become available in our online store.

* Licences for Visual Lint 1.x through 5.x can be upgraded manually - please contact us for details.

Customers with active Visual Lint 7.x priority support subscriptions should already have received updated licence keys for the new version.

Visual Lint floating and site licence subscription customers have the option of continuing with Visual Lint 7.0 until their next renewal or updating to Visual Lint 8.0.

In addition, all customers who have purchased per-user or per-server Visual Lint licences since 1st January 2021 are also eligible to receive new Visual Lint 8.0 compatible licence keys.

If any of the above applies and you need a licence key compatible with Visual Lint 8.0 please contact us, quoting your order number and licence key.

 

Among the many changes included in Visual Lint 8.0 is the addition of support for Clang-Tidy - an open source C++ analysis tool from the LLVM Project which is notable for its ability to automatically correct many of the issues it finds.

The Clang-Tidy Analysis Configuration Dialog allows you to configure the Clang-Tidy checks to be used.

The Clang-Tidy Analysis Configuration Dialog allows you to configure the Clang-Tidy checks to be used.

You can read more about the integration of Clang-Tidy into Visual Lint in the blogpost Clang-Tidying up the house.

 

The following changes are included in Visual Lint 8.0:

    Host Environments:

    • Projects whose physical location is defined using system environment variables within Visual Studio, AVR Studio 5.0 or Atmel Studio solutions (.sln, .avrsln or .atsln) files can now be loaded correctly.
       
    • Improved support for Eclipse project/build variables. In particular, variables of the form ${workspace_loc:/<ProjectName>/<resource_path>} and ${workspace_loc:/${ProjectName}/<resource_path>} should now be resolved correctly, even if the project is physically located outside of the workspace folder and <resource_path> is a linked resource.
       
    • Updated the values of _MSC_VER and _MSC_FULL_VER in the Visual Studio 2017 PC-lint Plus compiler indirect file co-rb-vs2017.lnt to support VS2017 v15.9.34.
       
    • Updated the values of _MSC_VER and _MSC_FULL_VER in the Visual Studio 2019 PC-lint Plus compiler indirect file co-rb-vs2019.lnt to support VS2019 v16.9.2.
       

    Analysis Tools:

    • Added support for the Clang-Tidy analysis tool. Clang-Tidy is an open source C++ analysis tool from the LLVM Project which is especially notable for its ability to automatically fix some of the analysis issues it detects.
       
    • Updated the PC-lint Plus message database to reflect changes in PC-lint Plus 1.4.
       

    Installation:

    • Added PC-lint Plus library indirect files lib-rb-stl.lnt and lib-rb-boost.lnt.
       
    • The PC-lint Plus library indirect file lib-rb-win32.lnt no longer includes tuning directives for the ATL, WTL and MFC libraries - instead, dedicated indirect files for these libraries (lib-rb-atl.lnt, lib-rb-wtl.lnt and lib-rb-mfc.lnt respectively) are now supplied.

      If you analyse ATL, WTL or MFC code your PC-lint Plus analysis configuration will need to be updated accordingly. The implementations of lib-rb-win32.lnt for PC-lint 8.0 and 9.0 are unaffected.

    Configuration:

    • Added a "Exclude files matching these wildcard masks" option to the Advanced Analysis Options Dialog. This can be used to (for example) automatically exclude generated files such as Qt moc_*.cpp files from analysis. Multiple masks can be specified by delimiting them with semicolons.
       
    • Revised the .vlconfig file format. The changes are backward compatible, so old format files can still be read and will be updated when saved.
       
    • Analysis Configuration files now include the name and major/minor version of the product which wrote them. Note that the full build version is not included, as that could cause unnecessary diffs in the resultant .vlconfig files.
       
    • Added the ability to override the preprocessor symbol and include folder properties of arbitrary project types using the Project Properties Dialog. This allows the analysis configuration of a project to be further customised (e.g. by injecting additional preprocessor symbols) without affecting the build environment. If the properties of the project are overridden in this way, a <projectfilename>.vlproj file will be written alongside the project file to store the overridden properties. [Visual Lint Professional, Enterprise and Build Server Editions]
       
    • Various changes to the implementation of options.
       

    Analysis:

    • The "Auto" value of the Maximum background analysis tasks option now allocates threads at 75% of the CPU logical core count.
       
    • Manual analysis can now optionally automatically fix some detected issues. To enable this option, select Clang-Tidy as the active analysis tool and check the "Apply suggested fixes" option in the Clang-Tidy Analysis Configuration Dialog. [Visual Lint Enterprise and Build Server Editions]
       

    User Interface:

    Commands:

    • The "Insert Directive" command on the Analysis Results Display context menu can now also be used to suppress Clang-Tidy analysis issues.
       
    • The "Lookup Meaning" command on the Analysis Results Display context menu is now available when analysing with CppCheck or Clang-Tidy.
       
    • Added an "Apply Fixes" command to the Analysis Status Display context menu. This command applies all fixes identified by Clang-Tidy to the selected implementation files.
       
    • Added a "Troubleshooting | View Fixes" command to the Analysis Status Display context menu. This command displays the contents of the Clang-Tidy .fixes file (if any) corresponding to the selected implementation file. These are YAML files associated with the clang-apply-replacements tool and which contain details of the issues Clang-Tidy has identified - and any changes it identified to fix them.
       

    Bug Fixes:

    • Fixed a bug in the expansion of project variables in multi-field strings where more than one field expands to the same variable. This manifested in Visual Studio 2019 where the include path "$(VC_IncludePath);$(WindowsSDK_IncludePath)" only expanded the first instance of $(WindowsSdkDir).
       
    • Fixed a bug which could affect the parsing of VisualDSP project files in the 64 bit version of VisualLintConsole.
       
    • Fixed a crash which which could occur while generating a Clang-Tidy command line for a standalone source file which is not part of any project.
       
    • Fixed a bug in the Analysis Results Display charts when rendering summaries of issues with embedded quotes in the issue title.
       
    • Fixed a bug in the Analysis Statistics Display which could cause some issues to be incorrectly displayed with the wrong issue category. The bug was identified while adding support for Clang-Tidy to the display.
       
    • Fixed a bug in the Analysis Status Display "Delete Analysis Results" context menu command which could cause an analysis task to be created for a file which was excluded from background analysis.
       
    • Fixed a bug which could prevent affected source files from being marked as stale when a header file was changed. The bug was identified while adding support for Clang-Tidy.
       
    • Fixed a bug which could cause uncommitted changes in the Property List Dialog to be lost if the "Expand project variables" checkbox was checked.
       
    • Fixed a bug in the x64 build of the Eclipse plugin.
       
    • Fixed a minor bug in the "Command Line" Options page.
       
    • Parsing operations on MSBuild project files can now be aborted part way through. This should make certain operations (e.g. changing configurations immediately after loading a solution) more responsive.
       
    • The Display Filter will no longer automatically attempt to suppress instances of issue 974 (note -- worst case stack usage...) if the active analysis tool is not either PC-lint or PC-lint Plus.
       
    • The Solution/Project Analysis Configuration Dialog now resizes correctly.
       
    • Corrected the tab order of the Solution/Project Analysis Configuration Dialog.
       

Download Visual Lint 8.0.0.335

OKRs in Agile Q&A part 2: The Backlog

Allan Kelly from Allan Kelly Associates

Continuing from my last post and more questions arising from my Reawakening Agile with OKRs talk.

In my OKR book I advice teams to forget about the backlog and instead use the OKRs as a story generating machine. As I expected, this grabs people’s attention. For many this might be the most surprising piece of advice in the boo, and perhaps the most controversial.

So it is hardly surprising that there were several questions around this:

Q1: If the backlog isn€™t a reflection of what we need to do in order to move towards our vision what is it for?

Exactly. If the backlog does not reflect your vision then what is the point of a backlog?

First off, if the backlog is aligned with your vision, and things are working well then why change? Certainly don’t add OKRs unless they are addressing a problem, and when you add OKRs see if there is anything else you can remove. If OKRs are simply repackaging the backlog then why both? Why add to the tools and processes in use?

For a few fortunate teams that is indeed the case. However, for many teams the backlog also contains a multitude of work which is not part of the vision and requested fixes. The backlog long ago became a dumping ground for requests.

Yet removing work from the backlog becomes hard. Product Owners feels they lack the authority or confidence to actually say “No, we will not do that.” At the same time the teams performance is judged by “how much backlog” gets done. Success or failure come down to “is the backlog done?” Thus the backlog comes into conflict with the OKRs.

In the book I introduce Jeff Bezo’s “Day 1” approach where company works as if today is the first day and questions what they are doing. OKR setting needs to be a day-1 experience.

Q2: Backlog needs reviewing to align with OKRs, surely?

That is one approach, set the OKRs and then before or during every planning meeting comb through the backlog and find work which will move you towards the OKR. That will work if you have a few dozen items in the backlog but what if you have a thousand or more? What if the backlog has been passed down from a previous product owner or a requirements document? In both cases that work will be harder.

The bigger problem is: what if you think of something that is not in the backlog and will move you towards the OKRs?

Do you say No?
I expect not, I expect you will quickly write it, slip it into the backlog and say “look what I just found”

Now the backlog is a collection of ideas which might, or might not, help achieve the OKRs but which you might not do.

At which point, what is the point? Why not just brainstorm what you can do?

Q3: Isn’t OKR then a guidance to create Backlog? or prioritize it?

Create a backlog, yes, the OKR is guidance to create a backlog – its a story generating machine. So what is the point of having 500 stories which describe work not related to the current OKRs? Will not get done anytime soon? And likely will never be done? But which confuse the governance process and drawn everyones morale because “we still have 500 PBIs to do.”

Once you have your OKRs then there is little point in creating any more backlog then you will do in the next three months. You may generate 12 months of work but since OKRs are reset every three months the chances are three quarters of those stories will be thrown away.

So every quarter reset the backlog and start over. That is pretty much what I’m advocating.

Prioritizing the backlog, see Q2 above.

Q4: How have you approached the removal of backlogs? small experiment?
Q5: Have you done this in real life? How did you persuade people?

OK, you found me out, we didn’t actually throw the backlog away. There was some history in there which was useful and more importantly it would have drawn too much attention to the team. Instead we just ignored it.

This started as a small experiment between me – as Agile Coach – and the Product Owner: we just opted to ignore it.

We set the OKRs based on current priorities and strategy. Then in the planning meetings if we knew of a story in the backlog we pulled it up. But actually, this turned out to be more work than it was worth. Plus, by challenging the team we got better answers and more involvement.

It didn’t take long before the team noticed what was happening but I don’t think they minded much. Again they might say “O I know there is a story in there to do…” but more generally we just wrote new stories there and then: the OKRs were a story generating machine.

In the book I describe a further experiment I ran with another coach, as a result she came to the same conclusion: OKRs before backlog. While we shared this with other coaches – and indeed anyone who wanted to talk about it – we didn’t make a big fuss or publicise it. I’m doing that now.

Succeeding with OKRs in Agile

I see this approach as the logical conclusion of working with OKRs so I don’t think you need to make a fuss. You can just do it and I expect more teams to reach this conclusion. Except of course, those backlog-slaves who are labouring under corporate agile to burn-down the backlog!

Succeeding with OKRs in Agile is available in print or ebook format from Amazon now, an audio version will be out in the next few weeks. I will be repeating Reawakening Agile for Agile Newbury next month and discussing OKRs with Adrian Reed in May.


Subscribe to my blog newsletter and download Continuous Digital for free – normal price $9.99/£9.95/€9.95

The post OKRs in Agile Q&A part 2: The Backlog appeared first on Allan Kelly Associates.

Toggle window decorations on Linux GTK3 with Python3

Andy Balaam from Andy Balaam&#039;s Blog

The Internet is full of outdated Python code for doing things with windows, so here is what I got working today in a Python 3, GTK 3 environment.

This script toggles the window decorations on the active window on and off. I have it bound to Ctrl+NumPadMinus for easy access.

#!/usr/bin/env python3

import gi
gi.require_version('Gdk', '3.0')
gi.require_version('GdkX11', '3.0')
gi.require_version('Wnck', '3.0')
from gi.repository import Gdk
from gi.repository import GdkX11
from gi.repository import Wnck


def active_window(screen):
    for window in screen.get_windows():
       if window.is_active() == True:
            return window


def toggle_decorations(w):
    if w.get_decorations().decorations == 0:
        w.set_decorations(Gdk.WMDecoration.ALL)
    else:
        w.set_decorations(0)


screen = Wnck.Screen.get_default()
screen.force_update()
display = GdkX11.X11Display.get_default()
window = active_window(screen)
window_id = window.get_xid()

w = GdkX11.X11Window.foreign_new_for_display(display, window_id)
toggle_decorations(w)


window = None
screen = None
Wnck.shutdown()

Software engineering research problems having worthwhile benefits

Derek Jones from The Shape of Code

Which software engineering research problems are likely to yield good-enough solutions that provide worthwhile benefits to professional software developers?

I can think of two (hopefully there are more):

  • what is the lifecycle of software? For instance, the expected time-span of the active use of its various components, and the evolution of its dependency ecosystem,
  • a model of the main processes involved in a software development project.

Solving problems requires data, and I think it is practical to collect the data needed to solve these two problems; here is some: application lifetime data, and detailed project data (a lot more is needed).

Once a good-enough solution is available, its practical application needs to provide a worthwhile benefit to the customer (when I was in the optimizing compiler business, I found that many customers were not interested in more compact code unless the executable was at least a 10% smaller; this was the era of computer memory often measured in kilobytes).

Investment decisions require information about what is likely to happen in the future, and an understanding of common software lifecycles is needed. The fact that most source code has a brief existence (a few years) and is rarely modified by somebody other than the original author, has obvious implications for investment decisions intended to reduce future maintenance costs.

Running a software development project requires an understanding of the processes involved. This knowledge is currently acquired by working on projects managed by people who have successfully done it before. A good-enough model is not going to replace the need for previous experience, some amount of experience is always going to be needed, but it will provide an effective way of understanding what is going on. There are probably lots of different good-enough ways of running a project, and I’m not expecting there to be a one-true-way of optimally running a project.

Perhaps the defining characteristic of the solution to both of these problems is lots of replication data.

Applications are developed in many ecosystems, and there is likely to be variations between the lifecycles that occur in different ecosystems. Researchers tend to focus on Github because it is easily accessible, which is no good when replications from many ecosystems are needed (an analysis of Github source lifetime has been done).

Projects come in various shapes and sizes, and a good-enough model needs to handle all the combinations that regularly occur. Project level data is not really present on Github, so researchers need to get out from behind their computers and visit real companies.

Given the payback time-frame for software engineering research, there are problems which are not cost-effective to attempt to answer. Suggestions for other software engineering problems likely to be worthwhile trying to solve welcome.

Red Rebel Day: Did you know that 1 in 10 women can’t afford sanitary protection?

Paul Grenyer from Paul Grenyer

When Neelam Sultan asked me to support RedRebelDay I was keen to do what I could. It’s what you do when someone asks. It’s what I like to do when someone asks.

Then I attended the ‘ambassadors’ briefing, where a heavy emphasis was put on telling people what Period Poverty means to you. As a man this was quite daunting, especially as until recently the subject was still quite taboo for me. Especially as at least one of my former employees took great delight, and still does, in telling me when she had her period just to see the uncomfortable look on my face. What got me over it? Attending a Zoom call with 100+ women and a handful of men who were all talking very openly about periods and the problems 1 in 10 women face in affording sanitary protection.

Beyond the facts, that still didn’t help me understand what Period Poverty really means, let alone what it means to me. Then someone on the call described not being able to go to work or go to school or about your everyday life for a few days every month because you couldn’t afford something as simple as a sanitary product. This struck home for me, because I take being able to do these things for granted and I know how it feels when something beyond my control stops me from doing something I want to do. This is what Period Poverty means to me.

Will you help women live their lives in the way they deserve by donating to Red Rebel Day today? I have: 


Tea

Ticket Maps

Anthony Williams from Just Software Solutions Blog

It has been an increasingly common scenario that I've encountered where you have some ID that's monotonically increasing, such as a subscription or connection index, or user ID, and you need your C++ program to hold some data that's associated with that ID value. The program can then pass round the ID, and use that ID to access the associated data at a later point.

Over time, IDs can become invalidated, so the data associated with that value is removed, and you end up with a sparse set of currently-active IDs. You would therefore naturally lean towards using a map (whether a std::map, std::unordered_map or some other custom map) to associate the data with the ID.

Often such maps are implemented as node-based containers, which means that the nodes can be allocated at disparate memory addresses, which is bad for cache performance. Adding and removing nodes also always requires memory allocation/deallocation.

In his "Better Code: Relationships" presentation, Sean Parent describes an alternative implementation, which he calls the "Russian Coat-Check Algorithm". In this algorithm, the map is implemented as a vector of pairs of key/optional data. Because the keys come from a monotonically increasing index, the vector is always sorted, and inserts are always at the end. Entries can be removed by clearing the data, and if there are too many empty entries then the vector can be compacted. Lookups are always fast, because the vector is always sorted, so a simple binary search will find the right element.

Inspired by watching Sean's presentation at ACCU 2021 last week, I implemented what I call a Ticket Map (it maps a Ticket to a Value). This is an implementation of the algorithm Sean described, fleshed out to a full container. When you insert a value, it is assigned the next available ticket value. You can later access or erase the value using that ticket.

#include <string>
#include <iostream>
#include "ticket_map.hpp"

int main(){
    jss::ticket_map<int,std::string> map;

    auto ticket1=map.insert("hello");
    auto ticket2=map.insert("world");

    std::cout<<map[ticket1]<<" "<<map[ticket2]<<std::endl;

    map.erase(ticket1);
}

You can of course iterate through the container: in this case the iterators are Input Iterators, where the value_type is a std::pair<Ticket const&,Value&>. This allows you to access both the tickets and the raw elements, but also allows the iterator to provide a nice view over the data without exposing the std::optional implementation detail.

#include <string>
#include <iostream>
#include "ticket_map.hpp"

int main(){
    jss::ticket_map<int,std::string> map;

    auto ticket1=map.insert("hello");
    auto ticket2=map.insert("world");
    auto ticket3=map.insert("goodbye");

    for(auto& [ticket,value]: map){
      std::cout<<ticket<<": "<<value<<std::endl;
    }
}

The code is available on GitHub under the Boost Software License.

Enjoy!

Posted by Anthony Williams
[/ cplusplus /] permanent link
Tags: , ,
Stumble It! stumbleupon logo | Submit to Reddit reddit logo | Submit to DZone dzone logo

Comment on this post

Follow me on Twitter

On A Clockwork Contagion – student

student from thus spake a.k.

During the recent epidemic, my fellow students and I had plenty of time upon our hands due to the closure of the taverns, theatres and gambling houses at which we would typically while away our evenings and the Dean's subsequent edict restricting us to halls. We naturally set to thinking upon the nature of the disease's transmission and, once the Dean relaxed our confinement, we returned to our college determined to employ Professor B------'s incredible mathematical machine to investigate the probabilistic nature of contagion.

Questions about RFC 8771

Andy Balaam from Andy Balaam&#039;s Blog

During my work on RFC 8771 The Internationalized Deliberately Unreadable Network NOtation (I-DUNNO) I have come across a number of questions. I am documenting them here so I can send them to the authors and try to improve my understanding of the intention.

This is an excellent RFC, and I thank the authors for their efforts in creating it.

1. Non-printable characters

In 4.2. Satisfactory Confusion Level, the RFC states that encodings may be deemed Satisfactory if they contain ‘At least one non-printable character’ (as well as one other condition in this section).

Both of the existing implementations that I know of ( and ) interpret “printable” to mean the same as Python’s isprintable() function: that is Nonprintable characters are those characters defined in the Unicode character database as “Other” or “Separator”, excepting the ASCII space (0x20) which is considered printable.

However, the definition of this function may be rather Python-specific, since its intention appears to be related to language internals like the repr function.

It would be helpful to find out exactly what is meant by “non-printable character” in the RFC.

2. Are Modifier Symbols, Symbols?

Also in section 4.2, the RFC mentions ‘”A character from the “Symbol” category’.

The Python implementation excludes Modifier Symbols from its definition. I believe this is incorrect, and have logged an issue on the topic: Some Symbol characters not recognised as such.

It would be helpful to have clarification on this point.

3. What does “different directionalities” mean?

Unicode classifies characters into several Bidi_Classes (for example, U+CED6E is Left_To_Right). In section 4.3. Delightful Confusion Level, the RFC refers to ‘Characters from scripts with different directionalities’.

As far as I can see there are two possible interpretations of this phrase:

  1. The encoding should contain characters from at least two different Bidi_Classes, or
  2. The encoding should contain characters that are both left-to-right and right-to-left in direction, either weakly or strongly.

Both current implementations interpret this statement like number 1, but I suspect the intention may actually be something more like number 2.

If number 2 was meant, I think that would mean ignoring characters with Neutral directionality, and treating weakly directional characters as the same directionality as strongly directional ones.

4. What is a Confusable character?

Section 4.3 mentions ‘Character classified as “Confusables”‘. Both implementations interpret this quite loosely, as meaning something like ‘the encoding contains any character or substring which might be confused with any other character or substring’.

This means a lot of “normal” characters are included: all of the ASCII digits, and many of the Latin letters.

Was this is intention?

That’s all my questions. It has been great fun working on this RFC.