An organization allows its members to choose their own usernames. However, in order to counteract the proliferation of nonsensical usernames, the organization imposes the following restrictions:
usernames may only contain letters
usernames should be formed by discarding letters from the member's name (given name + surname)
The members of this organization have made a sport of looking for long existing words that satisfy these criteria. After all, if you're named Danny Kyung or Matthew Emes, the restrictions still open up the possibility of justifying the use of usernames such as dank1 (Danny Kyung) or memes2 (Matthey Emes).
From now on we can speak of Donald "Donut" Knuth (Donald Knuth) and Richard "Catalan" Stallman (Richard Stallman).
Write a function isvalid that takes two arguments: a username (str) and a member's name (str) that exists of a given name, a space and a surname. The function also has a third optional parameter length that may take a positive integer (int). The function must return a Boolean value (bool) that indicates whether the given username is valid for a member with the given name. This is the case if the username satisfies the two criteria imposed by the organization from the introduction. In testing these criteria, no distinction should be made between uppercase and lowercase letters. If a value $$n \in \mathbb{N}$$ is passed to the parameter length, usernames also should have at least $$n$$ letters to be valid.
Write a function usernames that takes two arguments: i) a collection (list, tuple or set) of member names and ii) the location (str) of a text file containing a sequence of words, with each word on a separate line. The function also has a third optional parameter length that takes a positive integer (int). This parameter has the same meaning as with the function isvalid. The function must return a dictionary (dict) whose keys are formed by all names (str) in the given collection. The dictionary must map each member name onto the set of all words (str) in the given sequence of words that are valid usernames for that member (according to the notion of validity as defined by the function isvalid).
In the following interactive session, we assume the text files usernames01.txt3 and usernames02.txt4 to be located in the current directory.
>>> isvalid('donut', 'Donald Knuth')
True
>>> isvalid('Aladin', 'Alan Turing')
False
>>> isvalid('Cannon', 'Claude Shannon', length=8)
False
>>> usernames(['Donald Knuth', 'Alan Turing', 'Claude Shannon'], 'usernames01.txt')
{'Donald Knuth': {'Donut'}, 'Alan Turing': {'Alanin', 'Anting'}, 'Claude Shannon': {'Cannon'}}
>>> usernames(['Ada Lovelace', 'Konrad Zuse', 'Grace Hopper'], 'usernames02.txt')
{'Ada Lovelace': {'dolce', 'adel', 'doel'}, 'Konrad Zuse': {'kade', 'knus', 'kous', 'oase'}, 'Grace Hopper': {'racer', 'chopper', 'rapper'}}
>>> usernames(['Ada Lovelace', 'Konrad Zuse', 'Grace Hopper'], 'usernames02.txt', length=5)
{'Konrad Zuse': set(), 'Ada Lovelace': {'dolce'}, 'Grace Hopper': {'rapper', 'chopper', 'racer'}}