Home > Net >  How can I properly use variables returned in other function / method?
How can I properly use variables returned in other function / method?

Time:11-26

Please bare with me since I am just starting to learn coding, and Python is my first language to go. I am a self taught and currently managed to find an internship in a startup. They asked me to make a chatbot for their website and I've managed to use an open source chatbot, using NLTK and Tensorflow, adapt it to our needs, and added a few new things to it, that's it. Managed to deploy it as well, and now is running successfully for more than a month. And so on I am working on the second project where I decided to build from scratch since it's not so complicated, but I struggle a lot with the OOP, can't really get to understand how the functions work, in a way that I can make an individual function and it does what it's supposed to, but the variable I return, I can't manage to call or use later on when I need it in another function. Can someone please help me understand the depth of it ? This is some code I extracted from the chatbot project, not something I build, and definitely not something I completely know how to build myself, but something I understand and been able to edit to my needs. Something I now try to inspire from when I build the structure of the functions in the new project I am working on.

def clean_up_sentence(sentence):
    sentence_words = nltk.word_tokenize(sentence)
    sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
    return sentence_words


def chatbot_response(msg):
    print("Message: %s" % msg)
    ints = predict_class(msg, model)
    if len(ints) == 0:
        return "Undskyld, kan ikke forstå dig. Prøv at stille et andet spørgsmål."
    res = getResponse(ints[0])
    if len(res) == 0:
        return "Undskyld, kan ikke forstå dig. Prøv at stille et andet spørgsmål."
    return res


def getResponse(intent):
    tag = intent["intent"]

    for i in list_of_intents:
        if i["tag"] == tag:
            return random.choice(i["responses"])


def bow(sentence, words, show_details=True):
    sentence_words = clean_up_sentence(sentence)
    bag = [0] * len(words)
    for s in sentence_words:
        for i, w in enumerate(words):
            if w == s:
                bag[i] = 1
                if show_details:
                    print("found in bag: %s" % w)
    return np.array(bag)


def predict_class(sentence, model):
    p = bow(sentence, words, show_details=False)
    res = model.predict(np.array([p]))[0]
    ERROR_THRESHOLD = 0.9
    before_filtering = [[i, r] for i, r in enumerate(res) if r > 0.0]
    results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD]
    # sort by strength of probability
    before_filtering.sort(key=lambda x: x[1], reverse=True)
    results.sort(key=lambda x: x[1], reverse=True)
    return_list = []
    for r in results:
        return_list.append({"intent": classes[r[0]], "probability": str(r[1])})
    before_filtering_list = []
    for r in before_filtering:
        before_filtering_list.append(
            {"intent": classes[r[0]], "probability": str(r[1])}
        )
    print("Before filtering: %s" % before_filtering_list[:3])
    print("After filtering: %s" % return_list)
    return return_list

And this is something I tried in the new project I am working on, not related at all with the chatbot. My code doesn't work and I can't manage to understand how to connect the methods and why to do it in such manner.

 man_coded_bag = []
woman_coded_bag = []

feminine_coded_words = [
    "agree",
    "affectionate",
    "child",
    "cheer",
    "collab",
    "commit",
    "communal",
    "compassion",
    "connect",
    "considerate",
    "cooperat",
    "co-operat",
    "depend",
    "emotiona",
    "empath",
    "feel",
    "flatterable",
    "gentle",
    "honest",
    "interpersonal",
    "interdependen",
    "interpersona",
    "inter-personal",
    "inter-dependen",
    "inter-persona",
    "kind",
    "kinship",
    "loyal",
    "modesty",
    "nag",
    "nurtur",
    "pleasant",
    "polite",
    "quiet",
    "respon",
    "sensitiv",
    "submissive",
    "support",
    "sympath",
    "tender",
    "together",
    "trust",
    "understand",
    "warm",
    "whin",
    "enthusias",
    "inclusive",
    "yield",
    "share",
    "sharin"
]

masculine_coded_words = [
    "active",
    "adventurous",
    "aggress",
    "ambitio",
    "analy",
    "assert",
    "athlet",
    "autonom",
    "battle",
    "boast",
    "challeng",
    "champion",
    "compet",
    "confident",
    "courag",
    "decid",
    "decision",
    "decisive",
    "defend",
    "determin",
    "domina",
    "dominant",
    "driven",
    "fearless",
    "fight",
    "force",
    "greedy",
    "head-strong",
    "headstrong",
    "hierarch",
    "hostil",
    "impulsive",
    "independen",
    "individual",
    "intellect",
    "lead",
    "logic",
    "objective",
    "opinion",
    "outspoken",
    "persist",
    "principle",
    "reckless",
    "self-confiden",
    "self-relian",
    "self-sufficien",
    "selfconfiden",
    "selfrelian",
    "selfsufficien",
    "stubborn",
    "superior",
    "unreasonab"
]

explanations = {
    "feminine-coded": (
        "This job ad uses more words that are subtly coded as feminine than words that are subtly coded as masculine (according to the research). Fortunately, the research suggests this will have only a slight effect on how appealing the job is to men, and will encourage women applicants."
    ),
    "masculine-coded": (
        "This job ad uses more words that are subtly coded as masculine than words that are subtly coded as feminine (according to the research). It risks putting women off applying, but will probably encourage men to apply."
    ),
    "strongly feminine-coded": (
        "This job ad uses more words that are subtly coded as feminine than words that are subtly coded as masculine (according to the research). Fortunately, the research suggests this will have only a slight effect on how appealing the job is to men, and will encourage women applicants."
    ),
    "strongly masculine-coded": (
        "This job ad uses more words that are subtly coded as masculine than words that are subtly coded as feminine (according to the research). It risks putting women off applying, but will probably encourage men to apply."
    ),
    "empty": (
        "This job ad doesn't use any words that are subtly coded as masculine or feminine (according to the research). It probably won't be off-putting to men or women applicants."
    ),
    "neutral": (
        "This job ad uses an equal number of words that are subtly coded as masculine and feminine (according to the research). It probably won't be off-putting to men or women applicants."
    ),
}


def men_coded_words(masc_bag, text):
    add_text = text
    man_coded_bag = masc_bag
    for word in masculine_coded_words:
        if word in add_text:
            man_coded_bag.append(word)    
    return man_coded_bag


def women_coded_words(fem_bag, text):
    add_text = text
    woman_coded_bag = fem_bag
    for word in feminine_coded_words:
        if word in add_text:
            woman_coded_bag.append(word)
    return woman_coded_bag


def analise_and_explain_results(text, count_man, count_fem):
 
    count_man_words = count_man
    count_man_words = len(man_coded_bag)

    count_woman_words = count_fem
    count_woman_words = len(woman_coded_bag)

    coding_score = count_woman_words - count_man_words

    strengths_of_coding = ""

    if coding_score == 0:
        if count_man_words:
            strengths_of_coding = "neutral"
        else:
            strengths_of_coding = "empty"
    elif coding_score >= 5:
        strengths_of_coding = "strongly feminine-coded"
    elif coding_score > 0:
        strengths_of_coding = "feminine-coded"
    elif coding_score <= -5:
        strengths_of_coding = "strongly masculine-coded"
    else:
        strengths_of_coding = "masculine-coded"

    return count_man_words, count_woman_words, strengths_of_coding


def get_results(text):
    user_input = text
    user_input = input("add text here:").lower()

    res = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag)

    # i am trying to use the returned variable strengths_of_coding and is not available.
    explain_results = explanations[strengths_of_coding]

    return res, explain_results

get_results("random text added here, really whatever for testing purposes")

Right, so when I am calling get_results('text'), I get this error and I know where it is coming from, "name 'strengths_of_coding' is not defined", but I just don't know how to access that variable and I've tried everything I knew I could try... I'm stuck here and a little bit frustrated because I understand it's a noob mistake, yet still I can't get the hang of it after two weeks of stress and frustration.

Any feedback is welcomed.

CodePudding user response:

strengths_of_coding is only defined inside the analise_and_explain_results function. When you return the values of that function, they are no longer attached to the names you used inside the function

return count_man_words, count_woman_words, strengths_of_coding can be also written as return (count_man_words, count_woman_words, strengths_of_coding) - it means the return value of the function is a tuple with 3 elements that are values of each of the variables, and that tuple is assigned to res in res = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag)

Value of variable called strengths_of_coding inside the function is available as res[2] in get_results after you do the assignment to res

CodePudding user response:

So it's hard to explain everything if you barely have any knowledge in OOP or coding in general. But in python, the return value of a function can be anything. None, a integer, a list, tuple, dictionary, object. Can even be a class definition. Only by looking at it, will you know exactly. That is called duck-typing; "If it walks like a duck and it quacks like a duck, then it must be a duck"

In this case, your analise_and_explain_results function does not return one thing, but several since it does this:

return count_man_words, count_woman_words, strengths_of_coding

So it actually returns a tuple with those three values inside. And these variables are scoped to that specific function, you cannot use them outside that function anymore. Note: For the sake of simplicity; let's just stick to not using them outside of the function since it's bad practice.

In your code, you then do this:

res = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag)

Which means that res at this point is actually the tuple holding the three values you are interested in. You have several ways to resolve this. But this easiest to follow is to just assign the values of variables like this:

count_man_words, count_woman_words, strengths_of_coding = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag)

This basically unpacks the tuple into three different values since it basically does this:

a, b, c = (1, 2 ,3)

Where before you did:

d = (1, 2, 3)

Unpacking is easy, as long as the item you unpack holds as many items as you're trying to assign;

a, b, c = d

If you have trouble grasping OOP and python I would suggest you learn to walk, before you run, which you're doing now IMO. Follow some tutorials or videos explaining OOP and python. Or combine them like they do on realpython.

CodePudding user response:

res = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag) turns res into a tuple with 3 elements. strengths_of_coding is the 3rd element in this tuple. So, you access it as res[2]. In python, when you return multiple stuff to one variable, the variable turns into a tuple. You can provide multiple variables to take each return. e,g, count_man_words, count_woman_words, strengths_of_coding = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag). Or, if you only need that one return then, strengths_of_coding = analise_and_explain_results(user_input, man_coded_bag, woman_coded_bag)[2].

  • Related