Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Richard Hummel
Courses Plus Student 5,677 PointsDo we need parameter in "add_to_list" function?
I am just curious in this function for the shopping list 2, where we add our items to the list in our new function, do we need the parameter? I was curious and did it without a parameter and it still works fine. What is the advantage to having the parameter? My code is below.
#make a list to hold our items
todo_list = []
#print out instructions on how to use the app
def show_help():
print("What should we do today?")
print("""
Enter 'DONE' to stop adding items.
Enter 'HELP' for this help.
Enter 'SHOW' to see the current list.
""")
show_help()
def show_list():
#print out the list
print("Here's your list:")
for each in todo_list:
print("~ " + each)
def add_to_list():
#add new items
todo_list.append(new_item)
print("Added {}. List now has {} items.".format(new_item, len(todo_list)))
while True:
#ask for new items to be added
new_item = input("~ ")
#be able to quit app
if new_item == "DONE":
show_list()
break
#have a HELP cmd
elif new_item == "HELP":
show_help()
continue
#have a SHOW cmd
elif new_item == "SHOW":
show_list()
print("Continue adding to your list.")
continue
add_to_list()
2 Answers
Chris Freeman
Treehouse Moderator 68,468 PointsIn small programs such as this, globals vs passing parameters is a question of convenience. You are actually using two globals: todo_list and new_item.
This wiki post on why Global Variables Are Bad provides good points, counter examples, and discussion. Highlights:
Why Global Variables Should Be Avoided When Unnecessary
- Non-locality -- Source code is easiest to understand when the scope of its individual elements are limited. Global variables can be read or modified by any part of the program, making it difficult to remember or reason about every possible use.
- No Access Control or Constraint Checking -- A global variable can be get or set by any part of the program, and any rules regarding its use can be easily broken or forgotten. (In other words, get/set accessors are generally preferable over direct data access, and this is even more so for global data.) By extension, the lack of access control greatly hinders achieving security in situations where you may wish to run untrusted code (such as working with 3rd party plugins).
- Implicit coupling -- A program with many global variables often has tight couplings between some of those variables, and couplings between variables and functions. Grouping coupled items into cohesive units usually leads to better programs.
- Concurrency issues -- if globals can be accessed by multiple threads of execution, synchronization is necessary (and too-often neglected). When dynamically linking modules with globals, the composed system might not be thread-safe even if the two independent modules tested in dozens of different contexts were safe.
- Namespace pollution -- Global names are available everywhere. You may unknowingly end up using a global when you think you are using a local (by misspelling or forgetting to declare the local) or vice versa. Also, if you ever have to link together modules that have the same global variable names, if you are lucky, you will get linking errors. If you are unlucky, the linker will simply treat all uses of the same name as the same object.
- Memory allocation issues -- Some environments have memory allocation schemes that make allocation of globals tricky. This is especially true in languages where "constructors" have side-effects other than allocation (because, in that case, you can express unsafe situations where two globals mutually depend on one another). Also, when dynamically linking modules, it can be unclear whether different libraries have their own instances of globals or whether the globals are shared.
- Testing and Confinement - source that utilizes globals is somewhat more difficult to test because one cannot readily set up a 'clean' environment between runs. More generally, source that utilizes global services of any sort (e.g. reading and writing files or databases) that aren't explicitly provided to that source is difficult to test for the same reason. For communicating systems, the ability to test system invariants may require running more than one 'copy' of a system simultaneously, which is greatly hindered by any use of shared services - including global memory - that are not provided for sharing as part of the test.
Why the Convenience of Global Variables Sometimes Outweighs the Potential Problems
- In a very small or one-off programs, especially of the 'plugin' sort where you're essentially writing a single object or short script for a larger system, using globals can be the simplest thing that works.
- When global variables represent facilities that truly are available throughout the program, their use simplifies the code.
- Some programming languages provide no support or minimal support for non-global variables.
- Some people jump through very complicated hoops to avoid using globals. Many uses of the SingletonPattern are just thinly veiled globals. If something really should be a global, make it a global. Don't do something complicated because you might need it someday. If a global variable exists, I would assume that it is used. If it is used, there are methods associated with it. Colocate those methods in a single class and one has created a singleton. It really is better to specify all of the rules for use of a global variable in one place where they can be reviewed for consistency. The veil may be thin, but it is valuable.
Richard Hummel
Courses Plus Student 5,677 PointsOk I got it now. Thanks!
Richard Hummel
Courses Plus Student 5,677 PointsRichard Hummel
Courses Plus Student 5,677 PointsOk...I get that global variables are viewed somewhat negatively...however since new_item is in a while loop it's still global, right? How does adding "new_item" to the "add_to_list" function not make it a global variable? Maybe I didn't ask the right question...in the video they use a parameter "new_item" in the "add_to_list" function, I didn't add it and it works...so what is the difference/advantage to using it as a parameter in the function?
Chris Freeman
Treehouse Moderator 68,468 PointsChris Freeman
Treehouse Moderator 68,468 PointsFirst, let me talk about namespaces. Namespaces are a dictionary of references. The top level of code sometimes called a module, has its namespace. Each function or class also has a namespace. When looking up a variable reference, the inner-most local namespace is checked first, then each layer outward until a match is found or a
NameErroris raised when not found anywhere. Variables references in the top-level module namespace can be seen by all code, thus are also referred to as "globals".Since the
whileloop doesn't create its own namespace, all its variables are in the top-level module namespace so are "global".When adding "new_item" to the function parameter list, the reference "new_item" is added to the function's local namespace. This "new_item" is different from the "new_item" found in the module namespace. The local "new_item" would reference the object passed to the function in the call:
add_to_list(some_object)which may or may not be the same as the global "new_item" object.In this small program, it doesn't make much difference. Why would one pass "new_item" as an argument, but still reference
todo_listas a global? Part of this coding example is to get used to passing arguments which will be necessary in larger programs so it is easier to track where variables are being referenced and set.I hope this helps!