Issue running a python function

Hi guys,

I’m trying to run a function that works perfectly well outside of Streamlit, but when I try to display the outcome of that function on my Streamlit App, it displays structural elements of my function instead.

The name of my function is “reco” - it’s basically a recommandation system for audio tracks. So when given a track, the function will advise you on another track to listen to.

Here’s the very beginning of what my function looks like in Python (but again, it works fine on its own) :

def reco(track):
df_track = dataset.loc[(dataset[‘artist_track’] == track)][[‘artists’, ‘track_name’, ‘artist_track’, ‘track_genre’, ‘cluster_genres’, ‘tempo’, ‘energy’, ‘loudness’, ‘popularity’]]
artist = df_track[‘artists’]

And here’s how I call it:

OG_track = “Taylor Swift - Blank Space”
if option != OG_track:
st.write(“You picked the track :”, option)
track = str(option)
reco1 = reco(track)

OG_track being a track used as an example, then the user can select another track using a selectbox.
Option is the outcome of what’s been selected using the selectbox.

If I select for instance the track Chris Stapleton - Tennessee Whiskey, here’s what’s displayed on my Streamlit App:

Any ideas on how to fix this? :frowning:

That is not in the code snippet though. What is the list of options that you are passing to st.selectbox? Is it some composition of df_track and artist values?

Here are the options passing to st.selectbox:

option = st.selectbox(“”, df[‘artist_track’].unique(),
index = 25369,
label_visibility = “collapsed”)

25369 is the index value of the Taylor Swift track that I use as a reference track.

What do you get as the type of option? Is it just a str or is it a numpy array?

(Could you share a link to a repo with the full code?)

Sure! Sorry, I should have done that right from the start.
Here’s a link to a repo with the full code: GitHub - juliefromthablock/streamlit

To answer your question, the type of option is a ‘str’ :+1:t3:.

The lists rendered on the app come from these lines that seem to be part of your .loc[] expression but they are actually independent statements, just because they are in new lines.

For example. you have this:

track_infos = dataset.loc[(dataset['cluster_attributs'] == j) 
& ((dataset['tempo'] > (k - 5)) & (dataset['tempo'] < (k + 5))) 
| ((dataset['tempo'] > ((k/2) - 5)) & (dataset['tempo'] < ((k/2) + 5)))
| ((dataset['tempo'] > ((k*2) - 5)) & (dataset['tempo'] < ((k*2) + 5)))
& (dataset['loudness'] > (l - 1)) & (dataset['loudness'] < (l + 1)) 
& (dataset['energy'] > (m - 0.2)) & (dataset['energy'] < (m + 0.2))
& (dataset['acousticness'] > (n - 0.3)) & (dataset['acousticness'] < (n + 0.3))
& (dataset['danceability'] > (o - 0.3)) & (dataset['danceability'] < (o + 0.3))]
[['artists', 'track_name', 'artist_track', 'track_genre', 'cluster_genres', 'tempo', 'energy', 'loudness', 'popularity']]

But you might wanted to do this:

track_infos = dataset.loc[(dataset['cluster_attributs'] == j) 
& ((dataset['tempo'] > (k - 5)) & (dataset['tempo'] < (k + 5))) 
| ((dataset['tempo'] > ((k/2) - 5)) & (dataset['tempo'] < ((k/2) + 5)))
| ((dataset['tempo'] > ((k*2) - 5)) & (dataset['tempo'] < ((k*2) + 5)))
& (dataset['loudness'] > (l - 1)) & (dataset['loudness'] < (l + 1)) 
& (dataset['energy'] > (m - 0.2)) & (dataset['energy'] < (m + 0.2))
& (dataset['acousticness'] > (n - 0.3)) & (dataset['acousticness'] < (n + 0.3))
& (dataset['danceability'] > (o - 0.3)) & (dataset['danceability'] < (o + 0.3))][['artists', 'track_name', 'artist_track', 'track_genre', 'cluster_genres', 'tempo', 'energy', 'loudness', 'popularity']]

Those statements that do nothing are interpreted by streamlit as things that are supposed to be rendered (see: Magic - Streamlit Docs).

I’d recommend simplifying those long filters on the df.loc[...] calls. Maybe take a look at pandas.DataFrame.query — pandas 2.0.2 documentation

Also, since you are calling this list multiple times, you could store it in a variable.

Thanks a lot for the insight! I’ll try to simplify the function as much as possible and have all conditions written on one line.

Will keep you posted on the result. Thanks again!

1 Like

Hi @edsaac, @Caroline, @tonykip,

I was able to solve the issue I had with the multiple statements, thanks to your help.
But there’s still a problem somewhere with my function, as Streamlit returns “None” instead of an actual value :thinking:

Not an streamlit issue, print statements do not return anything (here in the repo), that’s why you get None as the output of your own function.

return print(df_artist['artist_track'].values[:1]) # Always returns None

It must have something to do with the way I’m trying to run the function in Streamlit because the function does have a correct output when it’s being run outside of Streamlit :

It does not (:

When you call print(), that whole expression evaluates to None, even though it’s sending something to be shown in your screen.

Idk if this example helps, consider these three functions:

def fun1(x):
    return None
def fun2(x):
    return print(x)
def fun3(x):
    return x

You have a fun2, which is equivalent to fun1, but you are actually looking for fun3.

Edit: Here is probably a better explanation: python - Why does the print function return None? - Stack Overflow

1 Like

Ok gotcha! Thank you :slight_smile:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.