Learn Python the Hard way ex25 - Want to check my understanding
<p>total noob here confused all to hell about something in "Learn Python the Hard Way." Apologies if this has been covered; I searched and could only find posts about not getting the desired results from the code.</p>

<p>My question relates to the interaction of two functions in <a href="https://learnpythonthehardway.org/book/ex25.html" rel="nofollow">exercise 25</a>:</p>

<pre><code>def break_words(stuff):
    words = stuff.split(' ')
    return words
</code></pre>

<p>and</p>

<pre><code>def sort_sentence(sentence):
    words = break_words(sentence)
    return sort_words(words)
</code></pre>

<p>So, near the end of the exercise Zed has you run this in the terminal:</p>

<pre><code>&gt;&gt;&gt; sorted_words = ex25.sort_sentence(sentence)
&gt;&gt;&gt; sorted_words
['All', 'come', âgoodâ, âthingsâ, âthoseâ, âtoâ, âwait.â, âwhoâ]
</code></pre>

<p>Now I assume the argument in 'sort_sentence' comes from the following, entered in the terminal at the start of the exercise:</p>

<pre><code>&gt;&gt;&gt; sentence = "All good things come to those who wait."
</code></pre>

<p>But although we now know the above is the argument for 'sort_sentence,' 'sort_sentence' can't complete without running 'break_words', with 'sentence' again as <em>its</em> argument. Here's where I get confused: The argument for 'break_words' is labeled 'stuff.' Does this matter? Can 'sentence' just be passed into 'break_words' from 'sorted_words' no matter what the argument for 'break_words' is labeled?</p>

<p>So assuming what I assumed - that the argument label doesn't matter - 'break_words' ought to run with 'sentence' as its argument and return 'words', which is the output of the function 'stuff.split' contained therein. This is where I get <em>really</em> confused - what does the 'words' returned from 'break_words' have to do with the variable 'words' defined as a part of 'sort_sentence'? I simply can't figure out how these functions work together. Thank you in advance for your help!</p>

<p>How Python functions more or less work is the following:</p>

<pre><code>def function_name(parameter_name_used_locally_within_function_name):
    #do stuff with parameter_name_used_locally_within_function_name

    some_new_value = parameter_name_used_locally_within_function_name
    return some_new_value
</code></pre>

<p>Notice how the parameter is only with in the scope of the function <code>function_name</code>. As that variable will only be used in that function and not outside of it. When we return a variable from a function, we can assign it to another variable calling the function:</p>

<pre><code>my_variable = function_name("hello")
</code></pre>

<p><code>my_variable</code> now has <code>"hello"</code> as it's value since we called the function, passing in the value <code>"hello"</code>. Notice I didn't call the function with a specify variable name? We don't care what the parameter name is, all we know is it takes one input for the function. That parameter name is only used in the function. Notice how we receive the value of <code>some_new_value</code> with out knowing the name of that variable when we called the function?</p>

<p>Let me give you a more broad example of what's going on. Functions can be thought of a task you give someone to do. Lets say the function or task is to as them to cook something for us. The chef or task needs ingredients to cook with (that's our input), and we wish to get food back (our output return). Lets say I want an omelette, I know I have to give the chef eggs to make me one, I don't care how he makes it or what he does to it as long as I get my output/omelette back. He can call the eggs what he wants, he can break the eggs how he wants he can fry it in the pan how he likes, but as long as I get my omelette, I'm happy.</p>

<p>Back to our programming world, the function would be something like:</p>

<pre><code>def cook_me_something(ingredients):
    #I don't know how the chef makes things for us nor do I care
    if ingredients == "eggs":
        food = "omelette"
    elif ingredients == "water":
        food = "boiled water"
    return food
</code></pre>

<p>We call it like this: </p>

<pre><code>my_food_to_eat = cook_me_something("eggs")
</code></pre>

<p>Notice I gave him "eggs" and I got some "omelette" back. I didn't say the eggs are the ingredients nor did I know what he called the food that he gave me. He just return <code>food</code> that contain <code>omelettes</code></p>

<p>Now let's talk about chaining functions together. </p>

<p>So we got the basic down about me giving something to the chef and he giving me food back based on what I gave him. So what if we gave him something that he needs to process before cooking it with. Let's say what if he doesn't know how to grind coffee beans. But his co-chef-worker knows how too. He would pass the beans to that person to grind the coffee beans down and  then cook with the return process.</p>

<pre><code>def cook_me_something(ingredients):
    #I don't know how the chef makes things for us nor do I care
    if ingredients == "eggs":
        food = "omelette"
    elif ingredients == "water":
        food = "boiled water"
    elif ingredients == "coffee beans"
        co_worker_finished_product = help_me_co_worker(ingredients)
        #makes coffee with the co_worker_finished_product which would be coffee grindings
        food = "coffee"
    return food

#we have to define that function of the co worker helping:

help_me_co_worker(chef_passed_ingredients):
    if chef_passed_ingredients == "coffee beans"
        ingredients = "coffee grinding"
    return ingredients
</code></pre>

<p>Noticed how the co worker has a local variable <code>ingredients</code>? it's different from what the chef has, since the chef has his own ingredients and the co worker has his own. Notice how the chef didn't care what the co worker called his ingredients or how he handle the items. Chef gave something to the co worker and expected the finished product. </p>

<p>That's more or less how it's work. As long as functions get's their input, they will do work and maybe give an output. We don't care what they call their variables inside their functions cause it's their own items. </p>

<p>So let's go back to your example:</p>

<pre><code>def break_words(stuff):
    words = stuff.split(' ')
    return words

def sort_sentence(sentence):
    words = break_words(sentence)
    return sort_words(words)

&gt;&gt;&gt; sentence = "All good things come to those who wait."
&gt;&gt;&gt; sorted_words = ex25.sort_sentence(sentence)
&gt;&gt;&gt; sorted_words
['All', 'come', âgoodâ, âthingsâ, âthoseâ, âtoâ, âwait.â, âwhoâ]
</code></pre>

<p>Let's see if we can break it down for you to understand.</p>

<p>You called <code>sorted_words = ex25.sort_sentence(sentence)</code> and  set <code>sorted_words</code> to the output of the function <code>sort_sentence()</code> which is <code>['All', 'come', âgoodâ, âthingsâ, âthoseâ, âtoâ, âwait.â, âwhoâ]</code>. You passed in the input <code>sentence</code> </p>

<p><code>sort_sentence(sentence)</code> get's executed. You passed in the string is now called <code>sentence</code> inside the variable. Note that you could have called the function like this and it will still work:</p>

<pre><code>sorted_words = ex25.sort_sentence("All good things come to those who wait.")
</code></pre>

<p>And the function <code>sort_sentence()</code> will still call that string <code>sentence</code>. The function basically said what ever my input is, I'm calling it sentence. You can pass me your object named sentence, which I'm going to rename it to sentence while I'm working with it. </p>

<p>Next on the stack is:</p>

<pre><code>words = break_words(sentence)
</code></pre>

<p>which is now calling the function break_words with that the function <code>sort_sentence</code> called it's input as <code>sentence</code>. So if you follow the trace it's basically doing:</p>

<pre><code>words = break_words("All good things come to those who wait.")
</code></pre>

<p>Next on the stack is:</p>

<pre><code>words = stuff.split(' ')
return words
</code></pre>

<p>Note that the function call it's input as <code>stuff</code>. So it took the sort_sentence's input that sort_sentence called <code>sentence</code> and function <code>break_words</code> is now calling it <code>stuff</code>. </p>

<p>It splits the "sentence" up into words and stores it in a list and returns the list "words"</p>

<p>Notice how the function <code>sort_sentence</code> is storing the output of <code>break_words</code> in the variable <code>words</code>. Notice how the function <code>break_words</code> is returning a variable named <code>words</code>? They are the same in this case but it doesn't matter if one called it differently. <code>sort_sentence</code> can store the output as <code>foo</code> and it still work. We are talking about different scope of variables. Outside of the function <code>break_words</code> the variable <code>words</code> can be anything, and <code>break_words</code> would not care. But inside <code>break_words</code> that variable is the output of the function. </p>

<p>Under my house my rules? Outside of my house you can do what ever you want type of thing.</p>

<p>Same deal with <code>sort_sentence</code> return variable, and how we store what we got back from it. It doesn't matter how we store it or what we call it. </p>

<p>If you wanted you can rename it as:</p>

<pre><code>def break_words(stuff):
    break_words_words = stuff.split(' ')
    return break_words_words

def sort_sentence(sentence):
    words = break_words(sentence)
    return sort_words(words) #not sure where this function sort_words is coming from. 
                             #return words would work normally. 

&gt;&gt;&gt; sentence = "All good things come to those who wait."
&gt;&gt;&gt; sorted_words = ex25.sort_sentence(sentence)
&gt;&gt;&gt; sorted_words
['All', 'come', âgoodâ, âthingsâ, âthoseâ, âtoâ, âwait.â, âwhoâ]
</code></pre>

<p>You just have to think of local variables, and parameters as like just naming things to work with. Like our example with the chef, Chef might called the eggs, ingredients, but I called it what ever I wanted and just passed it "eggs". It's all about the scope of things, think of functions as a house, while you are in the house, you can name what ever objects you want in the house, and outside of the house those same names could be different things but inside the house, they are what you want them to be. And when you throw something out, you naming that item has nothing to do with the outside world, since the outside world will name it something else. Might name it the same thing tho...</p>

<p>If I just rambled too much, ask questions I will try to clear it up for you.</p>

<p>Edited</p>

<p>Coming back from lunch I thought of variable as containers, They hold the values but you don't care what other people's containers are named. You only care about yours and when someone gives you something you put it in a container and name it something you care about that will help you know what inside it. When you give away an item, you don't give the container, cause you need it to store other things..</p>

python