Help appending value to "Choice List" field - using python .append()

SUMMARY

When using GetGrist’s formula column, Python’s native function [array].append() returns an error:

 #AttributeError

The formula it was being used on in pertinent part:

  return $Tags.append("Reminder")

Where “$Tags” is a field that is a “Choice List”.

update- the attributeError is cause by the fact that the Choice List is a ‘tuple’ object and is neither a list nor an array, and therefore it has no attribute ‘append’.

To correct this problem, I used a function to convert the tuple to a list ( list([tuple]).append([string]) ). This solved the error, but the formula still does not return anything useful.

GOAL

  • I have a field/column called TAGS that is typed as a “Choice List” field.
  • When a user adds a “due date” to the record, I would like my TAGS field to automatically have the choice “Reminder” added to the existing list of choices on that record.

DISAMBIGUATION

To be clear, I am asking how to append a value that is already available as a choice in a particular field , therefore this thread does not apply : How to auto-add choices on a Choice List Column?

SETUP DETAILS

Here are the options / choices that are available in the TAGS field:

  • Complaint
  • Check-in
  • Reminder
  • Training, etc

And here is the first part of my formula, the boolean test, that is useful and works as desired. It returns true whenever a user updates a records Notification_DueDt and forgets to update the TAGS field with “Reminder”:

if "Reminder" not in rec.Tags and $Notification_DueDt != None : 
    return ...

Now, here are different versions of the the entire formula (both the boolean test and the array / list modification function) , and this last part is the portion that is giving me trouble and refuses to return the desired values.

* Formula Version 1:

Here is the original version of the formula (which is the version I was using before learning that GetGrist choice lists return a tuple instead of an array or list):

if "Reminder" not in rec.Tags and $Notification_DueDt != None : 
  return $Tags.append("Reminder")

This version was completely scrapped for the reasons mentioned earlier (that a choice list returns an immutable tuple as opposed to an array or list).

* Formula Version 2 … no official error but still problematic

The following new formula that converts the TUPLE into a LIST and then attempts to append the new list value still suffers from odd behavior. This new formula,

if "Reminder" not in rec.Tags and $Notification_DueDt != None : 
  listTags = list($Tags).append("Reminder")
  return listTags

will return existing tags if I do NOT use “.append(‘Reminder’)” on line 2. But as soon as I use the formula exactly as typed above (including the “.append…” portion), it returns nothing.

REQUEST

  1. Please share thoughts regarding how to append a value to an array using native python functions or getGrist functions.
  2. Any thoughts on a work around if the python native function “append” will not work?

------------FINDINGS AFTER ORIGINAL POSTING------------

Upon further investigation, the specifics of the error are as follows:

AttributeError: 'tuple' object has no attribute 'append'

And after a quick google search, found this out:

A tuple is a list which cannot be rewritten once created so it cannot be modified at all. and you have used append() which adds some data to the tuple therefore there is this error. Instead of using a tuple declare it as a list using the square brackets.

Hi.

For either of your formulas, could you try doing list($Tags) + ["Reminder"] instead. Let me know if that works.

George

2 Likes

Thank you. That makes since!

Just an update…

By your suggestion, this works

if "Reminder" not in rec.Tags and $Notification_DueDt != None : 
  listTags = list($Tags).append(["Reminder"])
  return listTags

And predictably this still throws an #AttributeError exception

if "Reminder" not in rec.Tags and $Notification_DueDt != None : 
  listTags = list($Tags).append(["Reminder"])
  return listTags

Just wanted to share the exhaustive results for any one trying to learn who may benefit from my journey. :slight_smile:

Thank you @georgegevoian !

2 Likes

Have another question closely related to this thread…

How can I programatically append List Choices to a column if I cannot read the values in that field and write back to the same field?

For example, I have the following formula in my “$Tags” field, and it keeps giving me a circular reference error:

listTags = list($Tags)
if "covid" in LOWER($Certs_Disa):
  return list($Tags).append(["Covid"])

Hi @OSAcadiana_Jobs.

For regular formulas, you’ll run into that circular reference error whenever you reference the same column because it will see the reference to the same column inside the formula, and re-evaluate the same formula, causing a never-ending loop that the formula never breaks out of.

Fortunately, Grist has an additional type of formula called a Trigger Formula (Intro to formulas - Grist Help Center) that should work well for your use case. The documentation has some examples, but essentially this is a formula that evaluates only when certain columns in your table change. This can include the column with the trigger formula itself, and it provides a nice way to programmatically clean or transform your data after it is changed.

You can convert a formula column to a trigger formula by going to the formula section in the right panel, and clicking the “actions” dropdown, and selecting “Make into data column”. Then, you can type in this formula:

listTags = list(value)

if "Covid" in $Certs_Disa and "Covid" not in listTags:
  listTags.append("Covid")
elif "Covid" not in $Certs_Disa and "Covid" in listTags:
  listTags.remove("Covid")
  
return listTags

In addition to leaving “Apply to new records” checked below the formula editor, you’ll want to also check “Apply on changes to”, and select the current field and Certs_Disa. This means that whenever you edit the Tags column, or the Certs_Disa column is changed, the formula will be evaluated again.

The formula itself starts by saving the current contents of the Tags column into the listTags variable. Note the use of value in list(value); this is a special variable available to trigger formulas that is similar to referencing $Tags in a regular formula, but avoids the circular reference error you would normally run into. Then it checks whether “Covid” needs to be added or removed from the current contents of Tags. We make the necessary change (removing or appending), and finally we return listTags.

The formula assumes that Certs_Disa is a choice list that contains a choice option of “Covid”, but can easily be tweaked to support other types of columns.

I made a small example here that you can play around with: Grist

Hope this helps,
George

2 Likes

awesome, thank you for the detailed reply.

Somehow I kept reading “value” as “put some value here such as a string, number, variable…”

Then I realized you meant put the literal text

value

:man_facepalming:

2 Likes