How to construct plantcode from botanical name with stringtheory

I need to construct a unique plantcode given the botanical plantname
Handy when importing in bulk from different sources to avoid duplicates

IE
botanical name Code

Anemone ×hybrida ‘Honorine Jobert’ = ANHHJOBE
Anemone ×hybrida ‘Alba’ = ANHALBA
Anemone japonica alba = ANJALBA
Anemone hupehensis ‘Praecox’ = ANHPRAEC
Anemone ‘Praecox’ = ANPRAECO
Anemone nemorosa =ANNEMORO

Pseudocode

C#= Count the words from the botanical name
Case C#
 of 2 !There are always at least 2  words
   if 2e word start with ' or x 
      Upper(substract,1,2,botanical name)&Upper(substract,2,6,2e word)
   else
      Upper(substract,1,2,botanical name )&Upper(substract,1,5,2e word) 
   end
 of 3
    if 2e word start with x and 3e word start with '  
        Upper(substract,1,2,botanical name)&Upper(substract,2,1,2e word)&Upper(substract,2,5,3e word)
     else
        Upper(substract,1,2,botanical name)&Upper(substract,1,1,2e word)&Upper(substract,2,5,3e word)
     end
 of >3
    if 2e word start with x and 3e word start with '  
        Upper(substract,1,2,botanical name)&Upper(substract,2,1,2e word)&Upper(substract,2,1,3e word)&Upper(substract,1,4,4e word)
     else
        Upper(substract,1,2,botanical name)&Upper(substract,1,1,2e word)&Upper(substract,2,1,3e word)&Upper(substract,1,4,4e word)
     end
 end !case

Can anybody help to check this and change this into stringtheory code

PS I realised the code should be entered in the dct in the after insert and after update triggers. So it should be Clarion code and not Stringtheory

Hi Dirk

that does not follow. eg. Just define the st object in your dictionary as a global so that it is within scope. The ST docs for “Prime GUID fields” gives you some pointers:

go into dct and Create a global variable section in the dictionary. Call it G and give it a prefix of G

then create a global variable within that section called ST. Set the “Data Type” to Type and set the “Base Type” to StringTheory.

you would then refer to it as G:ST or g:st etc.

but you should be able to do it easily whether using ST or straight Clarion code. ST makes it easier as you can simply call split to break it up into words.

something like (untested)

nameIn  string(100)
codeOut string(8)

  code
  codeOut = nameIn[1 : 2]  ! always use first two chars

  g:st.setValue(nameIn,st:clip)
  g:st.split(' ')
  g:st.removeLines()
  g:st.setValueFromLine(2)
  if g:st.startsWith('x') or g:st.startsWith('''')
    g:st.removeFromPosition(1,1)   ! or... g:st.top(1)
    g:st.setLineFromValue(2)
  end
  if g:st.records() > 2
    g:st.setValueFromLine(3)
    if g:st.startsWith('''')
      g:st.removeFromPosition(1,1) ! or... g:st.top(1)
      g:st.setLineFromValue(3)
    end
  end
  
  case g:st.records()
  of 2
     codeOut[3 : 8] = g:st.getLine(2)
  of 3
     codeOut[3] = g:st.getLine(2)
     codeOut[4 : 8] = g:st.getLine(3)
  else
     codeOut[3] = g:st.getLine(2)
     codeOut[4] = g:st.getLine(3)
     codeOut[5 : 8] = g:st.getLine(4)
  end
  codeOut = upper(codeOut)

there are hundreds of ways to do these things but give that a go

cheers

Geoff R

Edit: check your data for the ‘x’ and single quote chars as I suspect that you may have unicode representations - I just noticed the ‘x’ looked a bit odd.

actually perhaps that is not necessary at all…

try creating a procedure like

GetPlantCode procedure(*string NameIn), string

make it global (ie. click on “Declare Globally” on the procedure’s property screen).

then you should be able to to call that procedure in your trigger code.

the GetPlantCode procedure can define a local ST object which would be better all round.

hth

Geoff R

I think given the ‘x’ and single quote are not what they seem, you can probably simplify the code a fair bit by eliminating all chars other than alphabetics and spaces:

GetPlantCode         PROCEDURE  (*STRING pNameIn)     
st      stringTheory
codeOut string(8)

  code

  st.setValue(pNameIn,st:clip)
  st.upper()
  st.keepCharRanges(' A-Z')
  st.split(' ')
  st.removeLines()

  codeOut[1 : 2] = st.getLine(1)
  
  case st.records()
  of 2
     codeOut[3 : 8] = st.getLine(2)
  of 3
     codeOut[3] = st.getLine(2)
     codeOut[4 : 8] = st.getLine(3)
  else
     codeOut[3] = st.getLine(2)
     codeOut[4] = st.getLine(3)
     codeOut[5 : 8] = st.getLine(4)
  end
  return codeOut

Why do you?

Isn’t the plant name unique? Trying to construct another unique code based on the plant name seems unnecessary to me?

If you want a primary key you could use AutoInc or a UUID?

Hi Geoff,
Thx a lot.
I changed it a bit (!change) for the strange x at the beginning of the second part

  st.setValue(pNameIn,st:clip)
  st.upper()
  st.keepCharRanges(' A-Z')
  st.Replace('X ','X')           !changed     
  st.split(' ')
  st.removeLines()

  codeOut[1 : 2] = st.getLine(1)
        
  case st.records()
  of 2
     if sub(st.getLine(2),1,1)='X'      !changed
       codeOut[3 : 8] = sub(st.getLine(2),2,6)         
     else       
       codeOut[3 : 8] = st.getLine(2)
     end       
  of 3
     if sub(st.getLine(2),1,1)='X'      !changed
       codeOut[3] = sub(st.getLine(2),2,1)    
       codeOut[4 : 8] = st.getLine(3)     
     else       
       codeOut[3] = st.getLine(2)
       codeOut[4 : 8] = st.getLine(3)     
     end        
  else
    if sub(st.getLine(2),1,1)='X'       !changed
       codeOut[3] = sub(st.getLine(2),2,1)
       codeOut[4] = st.getLine(3)
       codeOut[5 : 8] = st.getLine(4)            
     else                                
       codeOut[3] = st.getLine(2)
       codeOut[4] = st.getLine(3)
       codeOut[5 : 8] = st.getLine(4)
     end       
  end
  return codeOut

edit by GCR fixed formatting and incorrect codeOut[4 : 9]

Hi Geoff Bomford,

Good question. Plantcode is primairy used to sort and search without the x and ’ and space and -. Maybe i will use it also to avoid duplicates when importing and to distinguish between users input of plants (empty plantcode) and exchange only plantrecords with a plantcode between different users of this app.

PS Genus,species and Cultivar are 3 different fields in this app

Hi Dirk

I edited your post to show correct formatting of the code and also to fix one line in the code.

I am not really convinced the change for replacing the ‘X’ will work as you intend but I guess you will have to test it on your test data and see. It would seem more straightforward just to delete it so you do not have to test for it in the following code??

Anyway glad to have helped.

cheers

Geoff R

I’m with Geoff.

Sure, take things that are going to make sorting difficult out of the names you have been given, but I cannot see any value in your abbreviated name. Maybe works for the first few on the list, but your are taking just two characters from the “main” (i.e. not hybrid/culltivar part) of the name. So when you get to angelica and angelonia, they will also be AN. You probably don’t want three different plants all muddled together on the basis of what the second and third parts of the names are. Also, just for fun, this is what google says about anenome japonica alba:

Anemone japonica alba is a hybrid Japanese anemone cultivar, also known as Anemone x hybrida ‘Alba’ or ‘Honorine Jobert’, that produces single white flowers with yellow centers from late summer into fall.

So the first three the items on your list are just variant descriptions of exactly the same plant.

Hi Jon,

The Growers worlwide! use the Botanical names but i find it difficult to sort (find and make a unique key?). I have the whole name now in one field but can’t make it unique. Actually it even get’s worse because my clients can insert a record where X can be typed where × is ment.

ie
Aesculus × carnea ‘Briotii’
Aesculus ×carnea ‘Briotii’

Hi,

How about using a Soundex or Metaphone calculation? Or something like that…

Anemone ×hybrida ‘Honorine Jobert’ = ANMNBRTHNRNJBRT
Anemone ×hybrida ‘Alba’ = ANMNBRTLB
Anemone japonica alba = ANMNJPNKLB

Just my 0.02…

I think you would be best off storing the Genus by itself and indicator of whether the plant is a species, an in-genus hybrid or a mixed genus hybrid, and then the species/hybrid part of the name. You can show them what the name will look like as they go (to try and discourage them from adding the x themselves). Genus should be from a dropdown.

And in terms of sorting you might want to ignore quotation marks in the hybrid name.