tableau / TabPy

Execute Python code on the fly and display results in Tableau visualizations:
https://tableau.github.io/TabPy/
MIT License
1.56k stars 598 forks source link

Error in python script in Tableau Calculated field - I'm new to this.. Please help ! #319

Closed karnapatel closed 5 years ago

karnapatel commented 5 years ago

Environment information:

Describe the issue Hi I am new to using Tabpy. Infact this is my first attempt.

Question in hand: Trying to count the Number of "p"s from a customer name in Tableau Superstore database.

I tried using a python script to do so. I guess I'm just getting the formatting wrong.

I tried creating a calculated field with the following:

Num of Ps

it says the calculation is valid but its throwing an error

Please help !

Num of Ps ERROR

0golovatyi commented 5 years ago

@karnapatel In your script [Customer Name] column will be _arg1. There's no [Customer Name] available in the script as the script is not aware of the column or even Tableau Desktop/Server in general. Also there are no _arg2 and _arg3 as you only passing one argument ([Customer Name]).

You can check TabPy log file to see where specifically your script fails. I can guess what you actually need is something like

SCRIPT_REAL("
v = 0
for letter in _arg1:
  if letter in _arg2:
    v += 1

return v", 
ATTR([Customer Name]), ATTR([Pp]))
karnapatel commented 5 years ago

@karnapatel In your script [Customer Name] column will be _arg1. There's no [Customer Name] available in the script as the script is not aware of the column or even Tableau Desktop/Server in general. Also there are no _arg2 and _arg3 as you only passing one argument ([Customer Name]).

You can check TabPy log file to see where specifically your script fails. I can guess what you actually need is something like

SCRIPT_REAL("
v = 0
for letter in _arg1:
  if letter in _arg2:
    v += 1

return v", 
ATTR([Customer Name]), ATTR([Pp]))

@0golovatyi Hi thanks for the quick reply... with the changes you have explained its now showing an error with "ATTR([Pp])" it says "Reference to undefined field Pp"

if i put ATTR("Pp") instead then the error is gone but the result isnt coming out as expected. Count is 0 for all the customer names.

0golovatyi commented 5 years ago

@karnapatel I just guessed column name from your initial script the same as for [Customer Name]. Use the actual column name instead of [Pp].

karnapatel commented 5 years ago

@0golovatyi im sorry i didnt understand. What do you mean by "Use the actual column name instead of [Pp]." I was trying to pass the string "Pp" so as to compare every letter from the Customer's name to the letters P & p as I would have done in a .py file.

0golovatyi commented 5 years ago

@karnapatel If it a string can you just use it in the script instead of passing it? Something like

SCRIPT_REAL("
v = 0
for letter in _arg1:
  if letter in 'Pp':
    v += 1

return v", 
ATTR([Customer Name]))
karnapatel commented 5 years ago

@0golovatyi Thanks the error is gone but the output isnt as expected :/ its still showing 0 for every customer

the [Customer Name] argument thats passed in ATTR, does it take it as a string?

0golovatyi commented 5 years ago

@karnapatel Tableau passes [Customer Name] exactly as it is - if it is a string column it will be passed as a string.

What exactly are you trying to achieve with the script? Count number of letters p for each [Customer Name] entry?

karnapatel commented 5 years ago

@0golovatyi yes exactly.. trying to count the number of "p"s in a customer's name. struggling with this one exercise since 2 days now :(

num of ps not returning value

0golovatyi commented 5 years ago

@karnapatel Oh, I see. In the way you have written the script it looks like you want to count the number of p's for all customer names. What you need is to return a collection of the same size as input data so Tableau can match each entry in result with each row in the column. Have you read https://github.com/tableau/TabPy/blob/master/docs/TableauConfiguration.md?

I would guess again, but it seems like you need to iterate through all of the names and for every name create a new counter. And your return result should be a collection of counters.

Something like:

SCRIPT_REAL("
v = []
for name in _arg1:
  v.append(name.tolower().count('p'))

return v", 
ATTR([Customer Name]))
karnapatel commented 5 years ago

@0golovatyi it worked !! its counting absolutely fine now ! Thank you so much !!

just one last question. the result is showing as a float. how do i return it as an integer value instead?

0golovatyi commented 5 years ago

@karnapatel As mentioned at https://onlinehelp.tableau.com/current/pro/desktop/en-us/functions_functions_tablecalculation.htm#scriptint you'll need to use SCRIPT_INT for retrieving integer values in Tableau.

karnapatel commented 5 years ago

@0golovatyi thanks a lot !

sHinchman commented 3 years ago

@0golovatyi this was so helpful for me as I am trying to count the number of words in a string but was stuck. When i used your note and looked for " " spaces it worked. BUT it only works when my attribute for the string is in rows. If i remove the attribute to get a total sum for example it does not work. I imagine because my code is looking for the dimension.

How would I rewrite this to get a word count if my ultimate goal is to get an avg word count over time.

the data is structure in that there is 1 unique value per row over (survey data over time) current count gets a result only with SM_VERB_REASON_FOR_SCORE in the sheet (rows or columns)

SCRIPT_REAL( " v = [ ] for verbatim in _arg1: v.append(verbatim.lower().count(' '))

return v ", ATTR([SM_VERB_REASON_FOR_SCORE]))

I had to change to lower instead of tolower because i was getting an error otherwise. I also had to filter out NULL values because it was returning an error then too.

Thoughts?