Generate an ID from a company name

Hello every one,

Today I have script that I cannot even start as it is far too complicated for me to handle!
So I hope someone will be kind enough to show me the way how to start and I will try to finish it.

The script is to generate from a company name a unique ID with letters.

For example accompany name could be:
Tourist on Holidays forever Co. Ltd & corp.

Now I would like the script to generate an ID for each first letter of each words.
Result for this should be then TOHFCTAC the “&” should be replaced by the word “And” therefore picking up “A”

Then the script should look in a particular folder to see if this ID has not been used before.
If it has been used then it should change the second letter of the second word by its second letter then it should look like: TNHFCTAC and so on until it is unique.

Hope to hear from someone…

Thanks,

Hi,

I’d prefer to use a database for that purpose and create real independent unique identifiers.
AppleScript has built-in database support via Database Events which is simple but sufficient.
Maintenance and lookup is much faster than any other solution

If you don’t care too much if it’s human readable and a little flexible on the “must contain letters”, then you could create a hash of the company name string

set companyName to "Tourist on Holidays forever Co. Ltd & corp."
set hashSTR to do shell script "md5 <<< \"" & companyName & "\""
log hashSTR

returns: “8d6b9e7b611960238b16b649f5635e04”

Run this a million times and you’ll always get “8d6b9e7b611960238b16b649f5635e04”

Thank you Stefan for your suggestion.

I’d rather not use a database because no matter what I am already using this structure run partly with excel formulas and manually checking if the ID has been used and modifying it if necessary.

It might be too complicated to undo what has been done in the past. I’d rather take it from here and try to accommodate my ID’s to what is existing and move forward.

The Company ID together with some other information helps me to organise files and folders for different tasks.

I would appreciate if you could suggest a piece of code to get started on generating the first 2 letters then I will try to finish the script.

Thanks again for your help.

Thank you Woggledog for your suggestion.

Actually as explained to Stefan the readable issue matters and the ID cannot be so long as in your suggestion as it becomes difficult to manage along with the other stuff I have combine with it.

Same question as to Stefan your help would be appreciated if you could show a starting point!

Thanks for your time.

This should get you started:

set myText to "Tourist on Holidays forever Co. Ltd & corp."

set myID to {}

set text item delimiters to {"&"}
set myText to text items of myText
set AppleScript's text item delimiters to {"A"}
set myText to myText as text
set AppleScript's text item delimiters to {""}
repeat with aword in (words of myText)
	set end of myID to aword's first character
end repeat

set myID to myID as text
set idTest to do shell script "tr a-z A-Z <<< " & quoted form of myID

If I understand well the original question, adayzdone script must be edited this way :

set myText to "Tourist on Holidays forever Co. Ltd & corp."

set myID to {}

set text item delimiters to {"&"}
set myText to text items of myText
set AppleScript's text item delimiters to {"A"}
set myText to myText as text
set AppleScript's text item delimiters to {""}
repeat with aword in (words of myText)
	set end of myID to aword's first character
end repeat

return myID as text
--> "ToHfCLAc"

Here is a version dedicated to 10.10.x which convert the ID into UPPERCASE.

use framework "Foundation"
use scripting additions

on makeCapsOf(aString)
	return (current application's NSString's stringWithString:aString)'s uppercaseString() as text
end makeCapsOf


set myText to "Tourist on Holidays forever Co. Ltd & corp."

set myID to {}

set text item delimiters to {"&"}
set myText to text items of myText
set AppleScript's text item delimiters to {"A"}
set myText to myText as text
set AppleScript's text item delimiters to {""}
repeat with aword in (words of myText)
	set end of myID to aword's first character
end repeat
set myID to makeCapsOf(myID as text)
return myID
--> "TOHFCLAC"

Yvan KOENIG (VALLAURIS, France) jeudi 22 janvier 2015 17:56:35

I forgot he wanted to replace the & with A

Hello.

It is always a good practice to restore the text item delimiters to their previous value. :wink:

set astid to my text item delimiters # Save First
# some code here
set my text item delimiters to astid # when we are done using them.

You’re right McUsr.
If my memory is right, it’s the first script since several years in which I failed to save/restore the TIDs.
Maybe it’s because I was just trying to achieve the task asked in the original question.

Yvan KOENIG (VALLAURIS, France) jeudi 22 janvier 2015 20:47:23

Hello Yvan.

I was just teasing you and adayzdone, and at the same time informing the OP that he should embellish the script with the two lines.

It may go well to not restore the text item delimiters most of the time, but I’m picky with with text item delimiters, because in the beginning of my scripting career I managed to rename the contents a folder by an applescript, with wrong text item delimiters . ( I ended up with a whole bunch of filenames containing “^”'s or “$”'s in the wrong places).


set myText to "Tourist on Holidays forever Co. Ltd & corp."
set thisCode to makeCodestring for myText
log thisCode
--> "TOHFCLAC"
set newCodeString to increaseCodeString for thisCode
log newCodeString
(*TOHFCLAD*)
on makeCodestring for aSentence
	
	set astid to my text item delimiters # Save First
	set myID to {}
	
	set text item delimiters to {"&"}
	set aSentence to text items of aSentence
	set my text item delimiters to {"A"}
	set aSentence to aSentence as text
	set my text item delimiters to {""}
	repeat with aword in (words of aSentence)
		set end of myID to aword's first character
	end repeat
	set myID to myID as text
	set my text item delimiters to astid # restore them 
	log astid
	set idTest to do shell script "tr a-z A-Z <<< " & quoted form of myID
	return idTest
end makeCodestring

on okCodeStrings for firstCode by secondCode
	if firstCode = secondCode then
		return false
	else
		return true
	end if
end okCodeStrings

on increaseCodeString for someCode
	
	set lastchar to character -1 of someCode
	if lastchar = "Z" then
		error "Hull is breached, last character was \"Z\"!"
	else
		set newchar to character id ((id of lastchar) + 1)
		set newCodeString to (text 1 thru -2 of someCode) & newchar
		return newCodeString
	end if
end increaseCodeString

Hello McUsr

You are assuming that the message which is the point of departure contain only ASCII characters.
It’s the kind of limit which I systematically refuse.
I apologize but for me, É, Œ and many other letters have the same rights than ASCII ones.
It’s why I didn’t use the coelacanth named “tr” but took benefit of ASObjC which is easily usable with 10.10.

Yvan KOENIG (VALLAURIS, France) jeudi 22 janvier 2015 22:10:32

I agree with you in general, but since OP is from China, I guess he’ll just meet characters within the ascii a-z range. If he has a company name with say É in it, then the É will be simplified to E, which I hope the OP can live with, or, we’ll have to make something different.

Whoa… Like we say in French when we are overwhelmed…

Thank you all for your time and help in here.:slight_smile:

While I was sleeping you guys worked hard to help on the script…Thank you all.

I’ll clarify different issues:

To Yvan, Thanks for your script but I still don’t run 10.10 (Because I am running quite a few scripts on Numbers and I am afraid to have to redo them… I am still on 10.9)so when I try your script I got an error message as such:

error “Can’t get framework "Foundation" of «script». Access not allowed.” number -1723 from framework “Foundation”

You are correct in your assumption that I might use different characters. Since I am French leaving in China I have to write sometimes in French using a qwerty keyboard…And I do not want even to go into Chinese characters…

To adayzdone, I ran you first suggested script and found that it reruns the expected result which is
tell current application
do shell script “tr a-z A-Z <<< ‘ToHfCLAc’”
→ “TOHFCLAC”
end tell
Result:
“TOHFCLAC”

To McUsrII Thanks for your suggested script and indeed it returns the expected result as well.
Would you be kind enough to explain the different actions of the script so that I can completely understand what it does?

I would like to understand where I can insert the lookup of the ID from my folders.
The rest of the script will search in a particular folder from a list of folder names that should look like:
“Old Folder names”
TOHFCLAC - Tours of Homes forever Co. Ltd & corp.

Our newly generated ID should be then:
TNHFCLAC - Tourist on Holidays forever Co. Ltd & corp.

Then if we have a new ID to generate with a different company name…
TOAFCLAC - Tropic on Harvest fever Co. Ltd & co.

So the script just looks at the first part of the folder name not the whole. Then adjusts the characters until the ID is unique.

One more little trick how can I just specify the number of words to be checked? Say maybe sometimes I might only use the 3 first words only to generate my ID.

Finally to explain what I use the ID for!
The ID will go in my address book as a special field.
Then I will collect this ID in different scripts to generate File names or folder names

Again thanks to all of you for your help

If you are using 10.9.x, you may use ASObjC too but the required code must be stored separately in a library file.

use framework "Foundation"
on makeCapsOf:aString
	return (current application's NSString's stringWithString:aString)'s uppercaseString() as text
end makeCapsOf:

Save this code in a Script package. I named it makeCapsOf.scptd.
Under 10.9.x, you must “bless” it. This requires that just after saving it you open a pane one the right edge of the script window in Script Editor and check a box.
I apologizes, 10.9 is an old beast for me and I already forgot the exact details.

Save the library file in the folder : “/Library/Script Libraries/” which you will perhaps have to create.

The main script become :

use theLib : script "makeCapsOf"
use scripting additions

set myText to "il était un petit navire & œuf"

set myID to {}

set text item delimiters to {"&"}
set myText to text items of myText
set AppleScript's text item delimiters to {"A"}
set myText to myText as text
set AppleScript's text item delimiters to {""}
repeat with aword in (words of myText)
	set end of myID to aword's first character
end repeat
set myID to theLib's makeCapsOf:(myID as text)
return myID
--> "IÉUPNAŒ"

Here is a version treating only a predefined number of words :

use theLib : script "makeCapsOf"
use scripting additions

set nbAllowed to 3 # adjust to fit your needs
set myText to "il était un petit navire & œuf"

set myID to {}

set text item delimiters to {"&"}
set myText to text items of myText
set AppleScript's text item delimiters to {"A"}
set myText to myText as text
set AppleScript's text item delimiters to {""}
set theWords to words of myText
repeat with i from 1 to nbAllowed
	try # useful in case of nbAllowed greater that the number of words available
		set end of myID to first character of item i of theWords
	end try
end repeat
set myID to theLib's makeCapsOf:(myID as text)
return myID
--> "IÉU"

Yvan KOENIG (VALLAURIS, France) vendredi 23 janvier 2015 14:31:55

Hello. ClaudeB

I guess you’ll have to rename the folders so they start with the new name, this shouldn’t be much of a problem.

My idea was that you “makeCodestring for aSentence” first, then test against all of your other code strings that you have in a list or something, which okCodeStrings kind of demonstrates, using this approach is more laborious for your part, because then you had to iterate over the whole code list, if you had a list containing all the codes that are used, then you could just test if the generated code was in that list.

if there was a “collision” (the handler found the same code), then you call “increaseCodeString for someCode” , and test again, until either no match was found, or Z was reached, (you could add an A when Z is reached, should that ever happen).

I wrote a general handler for returning a number of words in a sentence, it is general, so you’ll have to specify the startword, it is beyond your needs, but it shouldn’t be a problem for using it anyway, as you just specify 1 for the start.

to someWords for aSentence by numWords from startWord
	-- we must assume the '&' have been replaced with And
	--Assumes we don't pad any missing words with a's
	
	if startWord < 0 then
		set startWordTest to -startWord
	else
		set startWordTest to startWord
	end if
	
	tell aSentence
		set wc to count words
		if ((wc - startWordTest + 1) ≥ numWords and numWords ≥ 1 and (startWordTest ≤ wc and startWordTest ≥ 1)) then
			
			set selectedWords to words startWord thru -1
			set selectedWords to items 1 thru numWords of selectedWords
		else
			set selectedWords to {}
		end if
		
	end tell
	
	if selectedWords is {} then
		if numWords = 0 or startWord = 0 then
			error "someWords: 0 is an illegal value"
		else if wc < numWords then
			error "someWords: Not enough words in the sentence (range-error), was: " & wc & " needs: " & numWords
		else if (wc - startWordTest + 1) < numWords then
			error "someWords: numWords out of boundary (range-error), absvalue must be equal or lesser than : number of words in the sentence- abs(startWord) + 1 ( " & (wc - startWordTest + 1) & " ) was: " & numWords
		else if (startWordTest > wc) then
			error "someWords: startWord out of boundary (range-error), it's absvalue  must be equal or lesser than : number of words in the sentence  ( " & wc & " ) was: " & startWordTest
		end if
	else
		tell (a reference to my text item delimiters)
			set {astid, contents of it} to {contents of it, space}
			set sentenceStart to selectedWords as text
			set contents of it to astid
		end tell
		return sentenceStart
	end if
	
end someWords

Before I write something for you that filters foldernames for code, I’d like to know where the folders are stored, if they are stored on your machine locally, or on a server.

Edit
I made the handler above more “sane”, in that numWords now actually denotes the number of words in a sentence, and not the end offset of the words that is to be picked from a sentence.

And:
Fixed the range error tests and error messages!