SCRIPTING:

Tasha Tilberg
THE BACH CONVERTER
Given a set of chars (alphabets or numbers or user defined sets of char families) wider than a subset of the same lot, and given a string carrying chars of the former wider set, you can convert all the chars in such string taking as the pattern for this conversion the subset.

It is likewise with musical pieces whereas you can have many notes yet they all belong to the basic subset of the 7 main notes and differ from them only because they may be located at different octaves.
October 2003
{ @ }

The model above is Tasha Tilberg
LOADS OF TASHA TILBERG ON THE NET


PURPOSE OF THE SCRIPT
Why and how it has been envisioned

I presume the most immediate way to grasp what this script is meant for, is to explain how I first came to think of it.
I was reading a book by Douglas Hofstadter titled "Goedel Escher Bach", and there I learned that once J.S.Bach turned his own second name (Bach, that is) into notes.
In fact as you may know musical notes in anglo saxon countries (and in germany too) are labeled with alphabetical letters: A B C D E F G, and germany adds also a H because the B is meant not for a tone (one of the, so to say, white keys on a piano-forte) but for a semitone (one of, so to say, the black keys on a piano-forte). Thus it was quite possible to transform that name into a set of 4 consistent notes (and then Bach elaborated, obviously, a Canon on them, namely a set of variations from that small starting nucleus).

Consequently, I thought: what if his name wouldn't have been Bach but, say, Smith? How would have he translated an s or an m or an i?
Obviously, the answer is that if we conceive whatever set of chars as nothing but a subsequent list of the same subset of notes just stretching throughout more octaves, a letter higher than H should just have had to be transformed accordingly to the pretence it was just a higher octave.
Thus the correspondence might be as follows:

A B C D E F G   A B C D E F G   A B C D E F G   A B C D E
A B C D E F G   H I J K L M N   O P Q R S T U   V W X Y Z

I have given to the script a higher amount of flexibility though: you can include in it bases or alphabets much more complex than just mere single chars if you want. For more details see the instructions on the function arguments. Also, just to be complete, there is on this website a script which has a remote resemblance with this, the Leap Loop of an Array.

You have to feed the bachConverter with 5 arguments:

a james whistler painting
James Abbott Whistler, At The Piano, 1859; Cincinnati Taft Museum
SCRIPT ARGUMENTS
INPUT
Mandatory.
The incoming string whose chars have to be converted (that is, the so to go on with our musical metaphor, the full partita of notes: the music).
These can be whatever type of chars as long as they are included also in the following arguments of the script. As you will note reading on, if you want just to pass plain chars you can certainly do it, yet nothing prevents you from passing to it notes no longer described from just one char but by, for instance, full words or sets of chars: in the latter case you have to separate them with a specific separator - read what follows.
ALPHABET
Mandatory.
This must be the full alphabet including all of the chars that may recur in the input, for instance all the chars from A to Z: by z default the script assumes a case in sensitive set of letters from A to Z. They must be in the order you want to be considered as the order of the musical octaves - that is, imagine the set of chars like a group of keys on a piano, they constitute a coherent sequence.

If these notes are not represented by mere chars but by words or symbols made up of more than just one single char (that is, nothing would prevent you for considering the word "hallo" as the note, say, D) you then have to separate them with a predefined separator which you'll have to specify in the separator argument.
BASES
Mandatory.
This must be the "notes". If they are not chars but words (see argument above) they must be separated by the same specified separator you provided for the alphabet argument.

Additionally, the bases do not actually need to be consecutive elements within the alphabet argument: the script will verify where the bases are located within the ordered alphabet, and will calculate the octaves for each converted input char or word accordingly to how many octaves higher or lower from the collocation of the given base within the alphabet.
SEPARATOR
Optional. It defaults to an empty string, but if you arranged your alphabets and bases as composed of more than just single isolated chars (such as words) then you have to provide a separator suitable to be used to distinguish one word from the other: if you want it to be a white space (the most natural choice obviously) you do have to pass this argument as a white space in between quotes: " "

All the arguments INPUT, ALPHABET, BASES can be passed as arrays as well if you prefer, the script will take care to return them in the same fashion you provided them: if they are passed as an Array the separator argument won't be necessary actually.
Remember: if a separator argument is passed, it means that such separator is present within all the first three arguments in order to separate item from item if such arguments are passed in the String format.
CASETYPE
Optional. The script is by default case INsensitive (if it sees that the currently inspected data is a letter or a word): if you want it to be case sensitive, you have to pass this last argument as something, arguably as number 1.
The function returns an array of 2 entries:
  1. entry [0]: The fully converted input string or array, returned either as a string or as an array depending upon how it was when passed.
  2. entry [1]: this second entry is more complex: it is an array itself on its own, whose each entry is another array of 2 entries: that is:
    output[1]=Array; then every output[1][x]=Array of 2
    therefore:
    output[1][x][0] and output[1][x][1]

    Of these last two entries, the first is a converted element, the second entry is a number representing which octave higher (positive number, whereas by higher I mean rightward as to the position the base has in the alphabet) or lower (negative number, whereas by lower I mean leftward as to the position the base has in the alphabet).

    Octaves are calculated considering whether an alphabetical (or whatever other data type, I just assume, in order to simplify, that we have surely to deal with letters) entry which is to be converted is higher or lower in its position within the alphabet than the position within such alphabet of, respectively, the higher and the lower extremes (top and bottom index positions in the array of) of the passed bases. So:
    • Is this letter lower than the lower base? if so, it is located at lower octaves.
    • Conversely, is this letter higher than the higher base? if so it is certainly located at a higher ocatve.
    • Is this letter the same as one of the bases? if so, it is on octave zero.
    • Or is this letter perhaps both higher than the lower base and lower than the higher base? It means bases are weird and jump positions or otherwise a letter that satisifies both conditions would have never been met (that is, the bases are not consecutive letters of the alphabet), thus we calculate octaves reckoning them by convention from the position of the higher base in the alphabet.
    So, the script would always convert the input: yet be warned the assignment of the octaves may seem weird if your bases are chosen in a weird way such as, say, XWB (see, non consecutive letter and also edges back to front: higher as first, lower as last!); about 40% of the length of the script is meant to accomodate these possibly weird bases and provide some logic in the assignment of the "octaves" in such cases, though in the actual runtime only one conditional statement more was necessary: this accomodation of werid bases is mostly performed before we enter the main loop.

    Anyway, example with an uncommon set of bases:

    Input: "hallo"
    Alphabet: "abcdefghijklmnopqrstuvwxyz"
    Bases: "ijy"
    thus the equivalences char by char are as follows:

    i j y i j y i j y i j y i j y i j y i j y i j y i j
    a b c d e f g h i j k l m n o p q r s t u v w x y z

    "Hallo" would translate into: "jiyyy"
    and the octaves are as follows:
    • H is turned into J and is -1 octaves (being our oversimplified base of 3 entries, each "octave" is actually made of 3 chars, thus the whole alphabets is ideally split into subsets of 3 chars, got it?) respect to i for h is lower than i which is the lower extreme of the bases.

    • A is turned into i and is -3 octaves (being our oversimplified base of 3 entries, each "octave" is actually made of 3 chars, thus the whole alphabets is ideally split into subsets of 3 chars, got it?) respect to i for also "a" is lower than "i" which is the lower extreme of the bases.
    • L is converted into y and is -5 octaves lower considering the position of L in regard to y in the alphabet: being L both higher than the lower base ("i") and lower than the higher base ("y") the calculation of the octaves in such case of such odd a set of bases is made, when a letter falls between them, accordingly to the higher bases.
    • O is turned again into y (that is its correspondence) and is -4 octaves lower respect to where y is in the alphabet.
      In our examples, just by chances, all "octaves" are in a leftward position in regard with the original collocation of each of our chosen bases in the given alphabetical sequence
    If a conversion exactly matches the position of the base in the alphabet, the number will be zero.
    If an input element which has no equivalent in the alphabet is found within the input, it is left in place as it is and the second entry will carry boolean false to signify that such entry is in no octave. This will happen also if a base is such that it recurs nowhere in the provided alphabet, because octaves cannot be calculated for a base set whose position in the alphabet is unknown - though I could have arranged by convention to consider it always as a phantasmal beginning: my suggestion, be always sure the bases exist within the passed alphabet or accomodate equivalences such that you can deal with bases present in the alphabet - though not necessarily in the input:
    bases within -> (wider)alphabet within->(wider?)input.
Keep in mind that the case insensitive procedures that are the default of the script may affect the original input too in case it was a globally defined variable: in fact the case insensitive feature is performed by lowering the case of its item -item.toLowerCase()- in case they were chars (that is, by the way: the function can work even with Data Types different than chars! In such case it won't be lowecased obviously: only letters or words can be lowercased).

Of course, you may argue why this script should be useful: well it certainly is for that specific instance I mentioned, but as you perhaps noticed, united scripters provides you with many scripts that either are quite more powerful than the average copy and paste scripts that you normally find online, or it is concerned with scripts that deal with unusual though fascinating issues. If you have no immediate need of this script, none the less keep it in mind it is here, for maybe one day you realize you face a task which might be solved exactly by this approach, by the Bach Converter!

As usual, a comprehensive Test Form is provided at bottom therefore you can also use it just to produce the bach conversion on an input and then use the input without actually having to meddle with the scripting issues involved with the actual codex.


THE CODEX AND THE TEST FORM
Get the code or test it to get acquainted with its workings

THE bachConverter CODEX
an august renoir painting
August Renoir, Young Ladies At The Piano, 1892; Musee d' Orsay, Paris
lines:
THE TEST FORM
INPUT:

ALPHABET:

BASES:

separator »        case INsensitive »         case sensitive »

         
INTERNALLY GENERATED EQUIVALENCES TABLE:
[possible apparently empty entries with the default example aren't but the white spaces]
OUTPUT:
[possible apparently empty entries with the default example aren't but the white spaces]


DETAILED OUTPUT
[possible apparently empty entries with the default example aren't but the white spaces]
Syntax Inspector: