Re: [Edu-sig] what is a "variable" in Python?

I agree with Gary that mutability is a property of objects, not of variables. An object has methods. A name does not - it can refer to an object with a particular method. I do not get the variable and remote buttons analogy at all. The importance of a variable naming a memory *location* with a reference is that clearly there can be only one reference at that memory location at a time. There is nothing saying with the English word "label" that two different objects/places could not have the same naming label slapped on them, so relying too heavily on easy English analogies is tricky. In my Hands-on Python Tutorial <http://anh.cs.luc.edu/python/hands-on/3.1> I say all data has a type, and I start with immutable objects types. I say initially that a variable is a name used to refer to a piece of data. Much later I get to mutable objects, and then the idea of a reference to an object is key to understanding. I point out that with immutable objects this does not make much difference, but when we start dealing with mutable objects, it is important to be more precise. This sequence seems to work fine. Andy Dr. Andrew N. Harrington Computer Science Department Graduate Program Director gpd@cs.luc.edu Loyola University Chicago 529 Lewis Towers, 111 E. Pearson St. (Downtown) 417 Cudahy Science Hall (Rogers Park campus) http://www.cs.luc.edu/~anh Phone: 312-915-7982 Fax: 312-915-7998 aharrin@luc.edu (as professor, not gpd role) On Mon, Feb 15, 2016 at 8:58 PM, kirby urner <kirby.urner@gmail.com> wrote:
On Mon, Feb 15, 2016 at 5:23 PM, Carl Karsten <carl@nextdayvideo.com> wrote:
I think the point of this thread is: how important is this subject?
I don't know that there's a scale of 1-10 answer. If / when it comes up, as a student question, it becomes important, but also instructors need to explain how a given object may have many names, whereas of we're focused on "containers" how does that look?
I have one of many answers: in my 2 hour 500 line intro to python, it gets about 60 seconds spent on this 1 line:
"""Other languages have variables; technically, Python doesn't. But it has something that looks like a var: It has names. So don't call it a var. For a good explanation of this see http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-... """
This is excellent.
I was racking my brains where to find visuals like this, specifically showing the buckets versus post-its models.
I've added links to my make_links_v2.py and make_links_v3.py @ <guild /> [1]
This thread was useful for our trains at PDX Code Guild at least, as I'm having philosophical differences with some of my peers regarding the uber-basics and how best to teach them.
I've been told repeatedly that code school students will start out *not* knowing what a variable is and my number one most important responsibility, right from the get go, is to introduce the concept.
Fine. But what if the curriculum hard-codes that we should see variables as "containers".
Before I lead a boot camp, Python-centric, I want to make sure I'm not shackled to a misinforming presentation I'm not comfortable teaching. It'd just feel wrong, like I'm lying, to force the "container metaphor". I needed ammo.
By now, thanks to these threads today, I feel well armed in my views that I'm free to avoid said metaphor if I want to.
Here's a screen shot of our faculty Slack feed from a few minutes ago:
There's enough consensus out there to defend my position. Yay.
What I want to avoid is another instructor insisting on the "variable as container" metaphor to a point where I feel I have to do extra work to undo that picture.
Thanks again for the tools, should that come up.
Kirby
[1] https://www.dropbox.com/home/PDX%20Code%20Guild/Accelerated%20Programming%20...

On Mon, Feb 15, 2016 at 8:48 PM, Andrew Harrington <aharrin@luc.edu> wrote:
I agree with Gary that mutability is a property of objects, not of variables.
I think everyone who has put in two cents so far, including me, agrees with this point. The only rewording I might suggest is "mutability is a property of objects, not names" (saying "names" instead of "variables") as I think it's fine to introduce Python to newbies without using the word "variable" (certainly not to mean "container" if used). "Names and objects" are sufficient to start with. Occam's Razor and all that. Some names aren't bound until run time, as happens when list(map(lambda x,y: x+y, ["T"], ["ED"])) actually executes: In[3]: list(map(lambda x,y: x+y, ["T"], ["ED"])) Out[3]: ['TED'] Names often get bound to objects without any need of the assignment operator. def F(): <function body> does name binding, of a name (F) to some callable object. The for loop is another example, of binding without need of the assignment operator (=): for x in H: body of loop shows how the same label, x, may be applied to items in succession. This x doesn't "contain" objects in H one by one, it merely tags them, and thereby gives code in the loop body an opportunity for controlling them. The assignment operator is a binding operator, in that it binds names to objects. Names do not "swallow" objects and take them prisoner. Names are not cells. Names have no internals. But then dot notation is often applied to them. aTV.on() controls some instance on the heap. aTV is a name with no TV "inside" it. aTV is remote from the TV, yet bound to it. Objects themselves are aptly modeled as containers, sure, and have both methods and data (typically) internally. Objects are what's complex. Names are simple (no internals). An object is typically mutable but of course not always -- an important distinction that should be front and center, once "naming" ("assigning") is understood.
An object has methods. A name does not - it can refer to an object with a particular method.
An object (noun) has these various verbs that we might call (__call__), but we do so using Python names (identifiers) most typically. 3 .__add__(2) makes sense, i.e. an int or string literal or "naked object" may be the subject of a method (e.g. "ABC".lower()). Usually though, we'd need a name for our objects, having no "naked" (syntactically primitive) form. The name anchors a surrounding namespace, of the methods and attributes therewith associated. A name is inside a namespace, and likewise comprises a namespace (with dot methods and dot attributes). The name remains distinct from the object itself in memory (on the heap). The TV remote idea is: if I aim a remote at a TV, it has __on__ and __off__ methods (so to speak). But if I "aim" a remote at (i.e. "bind" a remote to) another object type, then the "buttons" (the API, i.e. the methods) will be different. Only some types have __on__ and __off__. We all agree it's on the TV itself that channel changing happens (it's the TV itself that's mutable -- back to where we started, agreeing above). Going:
myTV = TV() myTV.change(6)
is making a mutable object's state mutate. myTV is not the object itself, it's a name for some object (and not a container of it either -- an image we don't need).
I do not get the variable and remote buttons analogy at all. The importance of a variable naming a memory *location* with a reference is that clearly there can be only one reference at that memory location at a time.
But once you have that name (what some call a "variable"), there's now so much more you can do, beyond simply naming. If S names a string, you can now S.upper() it, and if it's an int, you can S.__add__ it to something else. The name (remote) "sprouts buttons" (like off and on) in accordance with what type it aims at (binds to). The name has its dot methods and dot attributes, useful for changing that stuff in memory which actually does the work.
There is nothing saying with the English word "label" that two different objects/places could not have the same naming label slapped on them, so relying too heavily on easy English analogies is tricky.
How do I take the very same physical post-it, this very one, and affix it to two different objects at the same time? How would you draw that? It seems grammatically challenging. I suppose one could sort of half-affix it to two different objects and the same time. A luggage tag could loop through two suitcase handles. OK, you got me there: the English is ambiguous. However: how do five "containers" (known as "variables" in some narratives) all "contain" the "same" object, which they may be proved to do, using id(A), id(B), id(C) and so on? A,B,C,D,E all reference the very same object. What's the picture? How does it help to say these five names of the same thing are "containers" of that thing? Why do "buckets" make more sense that "post-its"? The object itself is a container (like a bucket), sure, in that it likely has / contains attributes (data), and is either mutable or not. So I'm willing to say the object is variable, in the sense of mutable, but that just grates on the ears of those who want to say "variable" to mean "Python name". Names of these objects by be known as "variables" but they are not containers and they only "vary" in the sense that names, like post-its, may be affixed to any object of any type. Integer or steam engine, it won't matter. So lets put to rest the idea that A,B,C... all "contain" the same object. There's no mental picture that's not messy in that case.
In my Hands-on Python Tutorial <http://anh.cs.luc.edu/python/hands-on/3.1> I say all data has a type, and I start with immutable objects types. I say initially that a variable is a name used to refer to a piece of data.
No problem with any of that. Or just say we use names to refer to data (objects). Who cares about "variables"? As opposed to what, "constants"? Do we call a luggage tag a "variable" just because it tags any suitcase? I suppose we could.
Much later I get to mutable objects, and then the idea of a reference to an object is key to understanding.
Sounds good too. remote = TV() # give me a way to control a TV instance remote.on() # now I'm controlling it, using the name (remote) remote.change_channel(6) # controlling it more (it being some thing on the heap) The remote is controlling something on the heap that may have many names. When it has no names, it gets garbage-collected.
I point out that with immutable objects this does not make much difference, but when we start dealing with mutable objects, it is important to be more precise. This sequence seems to work fine.
Sounds fine to me too. Tuples may have mutable elements, but are immutable in the sense of having just those elements (mutable or not, you can't add or remove them). That's an important discussion, and not "advanced" as the idea of appending to a list is as familiar as adding an item to a grocery cart. These concepts are mundane, routine, not even that abstract. They are anchored in ordinary language and everyday experience. OK, I think that's enough reiteration to keep it clear. Objects do all the work. Names are a means to that end, in providing the corresponding dot notation syntax. Kirby
Andy
Dr. Andrew N. Harrington Computer Science Department Graduate Program Director gpd@cs.luc.edu Loyola University Chicago 529 Lewis Towers, 111 E. Pearson St. (Downtown) 417 Cudahy Science Hall (Rogers Park campus) http://www.cs.luc.edu/~anh Phone: 312-915-7982 Fax: 312-915-7998 aharrin@luc.edu (as professor, not gpd role)
On Mon, Feb 15, 2016 at 8:58 PM, kirby urner <kirby.urner@gmail.com> wrote:
On Mon, Feb 15, 2016 at 5:23 PM, Carl Karsten <carl@nextdayvideo.com> wrote:
I think the point of this thread is: how important is this subject?
I don't know that there's a scale of 1-10 answer. If / when it comes up, as a student question, it becomes important, but also instructors need to explain how a given object may have many names, whereas of we're focused on "containers" how does that look?
I have one of many answers: in my 2 hour 500 line intro to python, it gets about 60 seconds spent on this 1 line:
"""Other languages have variables; technically, Python doesn't. But it has something that looks like a var: It has names. So don't call it a var. For a good explanation of this see http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-... """
This is excellent.
I was racking my brains where to find visuals like this, specifically showing the buckets versus post-its models.
I've added links to my make_links_v2.py and make_links_v3.py @ <guild /> [1]
This thread was useful for our trains at PDX Code Guild at least, as I'm having philosophical differences with some of my peers regarding the uber-basics and how best to teach them.
I've been told repeatedly that code school students will start out *not* knowing what a variable is and my number one most important responsibility, right from the get go, is to introduce the concept.
Fine. But what if the curriculum hard-codes that we should see variables as "containers".
Before I lead a boot camp, Python-centric, I want to make sure I'm not shackled to a misinforming presentation I'm not comfortable teaching. It'd just feel wrong, like I'm lying, to force the "container metaphor". I needed ammo.
By now, thanks to these threads today, I feel well armed in my views that I'm free to avoid said metaphor if I want to.
Here's a screen shot of our faculty Slack feed from a few minutes ago:
There's enough consensus out there to defend my position. Yay.
What I want to avoid is another instructor insisting on the "variable as container" metaphor to a point where I feel I have to do extra work to undo that picture.
Thanks again for the tools, should that come up.
Kirby
[1] https://www.dropbox.com/home/PDX%20Code%20Guild/Accelerated%20Programming%20...

First, add me to the chorus of people saying that using the term "variable" to categorize mutable objects versus immutable objects is counter to the way every programmer uses and understands the term "variable" to mean a* name *that can take on multiple values over the lifetime of a program. Sounds like you've already been convinced about this by the others, so I won't belabor that point here. So let's move on to the topic of "containers" versus "labels" as a metaphor for variables. I have used both, and I think both work equally well with students (but we can do better, more on that in a moment). Your main argument against containers is that it goes against real-world intuition to have one value in two containers. This is easy enough to rectify. Each container is designed to hold a piece of paper with enough space to write 64 0's and 1's. Putting something in a container simply means we write the 64 0's and 1's that describe where to find the object in the computer's memory -- an address -- and put that piece of paper in the container. No student has a problem with the idea of two containers, each containing their own piece of paper that happens to have the same number written on it. Arguably, the "containers of addresses" model is more precise than the label model. But we can do better than both the container and label model. The clearest teaching model: A variable is simply an entry in a dictionary. First, we need to talk about what it means for the Python interpreter to interpret or "evaluate" an expression. When I type x+y at the interpreter, what does that mean? How is that evaluated? Well, it's completely meaningless unless we know what the value of x and y are. Python keeps around a dictionary/table that stores associations between names and values. When I say x=2, all this means is that I'm adding an entry (or modifying an existing entry) in the main (global) dictionary that says x is now associated with 2. When I evaluate an expression like x+y, Python looks up the values for x and y in its dictionary. Right-hand sides of assignments are always evaluated first before an entry is put in the dictionary. So z=x first evaluates x, by looking it up (right now, it's 2) and then adding an entry in the dictionary between z and 2. (By using this more precise mental model, students now won't get tripped up by things like x=2, z=x, x=3 and thinking that somehow z has changed). Every function keeps around its own dictionary of name/value associations. When evaluating expressions inside a function, Python first tries to look up the name in the function's dictionary, and if not found there, works its way outward to the global dictionary (for beginners, there aren't likely to be more than two levels, so you can simplify this discussion a bit for beginners by talking about only two levels until you get to nested functions). When Python evaluates an assignment inside a function, it evaluates the right-hand-side using the rule just given, and then creates a new entry in the function's dictionary. (By using the more precise mental model, we've just explained some of the most complex intricacies of lexical scoping and how it behaves in Python, including a lot of surprising gotchas where people think they are assigning a global variable, but are actually just creating and assigning a new local variable.) I'm not opposed to giving simplified mental models to beginners and then later saying, "I lied before. It's really more complicated than that." But only if it's necessary. In this case, it's not. The dictionary model is more accurate, and no more difficult for students to understand. It's sort of like the label model, but more detailed because it tells us where these connections from labels to values actually live. This allows students to use their intuition they've developed from working with Python's dictionary data structure in order to understand how name/value associations are created, modified, and accessed. It provides far more context for understanding scoping. So I advocate for using this model from the start. The difference between the dictionary model and the label model is subtle, but it does require you to use different visual images to explain what is going on. Instead of showing objects put into boxes, or showing post-its attached to objects, when you step through a program on your whiteboard for the students, start off by drawing a big blank "piece of paper" off to the side labeled "dictionary". As you step through the program, write in new name/value entries on the dictionary. When you reassign a variable, find that name in the dictionary and erase the value that's there, and write in the new value. When you enter a function, draw another "piece of paper" near the function to contain its name/value associations. Give them this clearer visual imagery as you step through the program -- you'll be glad you did. When you want to get into mutability/immutability, instead of writing the actual value next to the name on the dictionary page, write the value at some random location on the board (you can draw a cloud to represent the computer's memory, and write the value in that area), and then the dictionary just contains the name and next to it an arrow to the value out in the memory (or use the address metaphor I described above if you prefer). This helps understand how two names can connect to the same object. Hope this helps, Mark

Advanced students can gain a much deeper understanding of variables by writing an interpreter themselves. This free course on udacity will show advanced students how to write a basic Javascript interpreter in Python: https://www.udacity.com/courses/cs262
participants (3)
-
Andrew Harrington
-
kirby urner
-
Mark Engelberg