Housekeeping Now is an excellent time to begin work on the assignment easy_functions.py These are fairly easy to write; use the documentation as a reference. Notice how I wrote test code for one of the functions. You can write this code before you try to write the functions.
If you find this a breeze, try medium_functions.py
.
The Ternary Operator This appears in the test code. Let's do an example or two.
def f(x):
return x if x >= 0 else -x
def g(x):
if x >= 0:
return x
else:
return -x
def result(x):
"""prec: x is 0 or 1
postc: returns "H" if x is 1 and "T" if x is 0"""
return "H" if x == 1 else "T"
What are the Stack and the Heap?
The Stack
The Heap
The stack is the portion of memory where all variables are stored along with the memory addresses of their objects. Remember, a memory address is just an integer, so the stack is where "small things" are stored. Access to its contents is rapid.
The stack's size is fixed during a program's lifetime. If you run out of room in it, you get a stack overflow error, and your program croaks on the spot.
The stack is also the mechanism by which function calls are managed. Every function call causes a data structure called a stack frame to be placed on the stack. When a function returns, its stack frame is popped (removed) from the stack. The stack frame stores all the function call's parameters, its local variables, and a return address, so when the function returns, the calling frame can pick up where it left off.
The heap is the data warehouse. Variables on the stack store the memory addresses of their object on the heap. Simply put, "Variables know where to find their objects." Your program can request more heap memory from the OS if it needs it. The heap is expandable, but not too expandable.
Every byte on the heap has a memory address that is an integer. Like the warehouse in the picture, locations are named so items can be quickly retrieved as needed. These addresses are called heap addresses.
Modern warehouse managers use computers to keep track of the contents of their warehouses. This software acts like the stack in a program. If the manager receives a request for items, he can check this software to see if he has them, and he can get any in-stock items into a delivery truck and on the way to the customer.
Program Life Cycle Consider this gigantic program.
hello.py
. We are going to probe its inner life in
intense detail.
print("Hello, World")
Observe that it has a function call in it to the print
function. Here is a blow-by-blow description of what happens.
- You launch the program by typing
python hello.py
. in a command window. - The OS grants a chunk of memory to the program you have launched.
- The global frame gets created and it is placed on the stack.
- The
print
function is called. It now gets a stack frame. This frame is put on top of the global frame. The stack now looks like this.------------------------- | print | | | ------------------------- | Global | | | ------------------------- Command Window --------------------------- | unix> python hello.py | | | ----------------------------
- The print function has the string
"Hello, World"
as its argument. This is a simple expression; its evaluation consists merely of creating it on the heap and assigning print's parameter, which we will calls
. This string will get created on the heap.Stack Heap ------------------------- ---------------------------- | print | | | | s ----------------------------------> "Hello, World" | ------------------------- | | | | | | | Global | ----------------------------- | | ------------------------- Command Window --------------------------- | unix> python hello.py | | | ----------------------------
This "pointing relationship" is possible because whats
is really storing the heap address of the string"Hello, World"
. We are usings
here because we actually have no idea what the real name for that local variable is. - The code in the
print
function now executes. As part of this execution"Hello, World"
is now put to the screen.Stack Heap ------------------------- ---------------------------- | print | | | | s ----------------------------------> "Hello, World" | ------------------------- | | | | | | | Global | ----------------------------- | | ------------------------- Command Window --------------------------- | unix> python hello.py | | Hello, World | ----------------------------
- As part of the creation of the
print
frame, the return address for the call is stored. This tells exactly where the caller, the global frame, has left off. Sinceprint
has done its job, it returns. When it does, its frame is removed from the stack.Stack Heap ---------------------------- | | | "Hello, World" | ------------------------- | | | | | | | Global | ----------------------------- | | ------------------------- Command Window --------------------------- | unix> python hello.py | | Hello, World | ----------------------------
- When we get back to the global frame, we discover that we are out of code. When a function runs out of code it does a tacit return. This causes the global frame to be removed from the stack.
- The removal of the global frame marks the end of execution.
The OS reclaims the memory your program was occupying.
What remains? The string
"Hello, World"
is sitting in your command window.Command Window --------------------------- | unix> python hello.py | | Hello, World | ----------------------------
Drawing diagrams like this helps you to understand what is happening in a program.
How Locality of Variables is Enforced
We will get down and dirty with the details for this call.
We name this program demo.py
def m(x,y):
return x*y
print(m(2 + 3, 5 + 7))
Stack Heap ------------------------- ---------------------------- | | | | | Global | | | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
m is read into memory.
Stack Heap ------------------------- ---------------------------- | | | | | Global m ------------------------------- CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
print is called and a frame is created.
.
Stack Heap ------------------------- | print | | | ------------------------- ---------------------------- | | | | | Global m ------------------------------- CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
Stack Heap ------------------------- | m x -------------------------------------5 | y --------------------------------------12 | return 60 | ------------------------- | print | | | ------------------------- ---------------------------- | | | | | Global m --------------------------CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
The function m returns the memory address of its value 60.
Stack Heap 5 12 ------------------------- | print s --------------------------------------60 | | ------------------------- ---------------------------- | | | | | Global m --------------------------CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
print prints 50
Stack Heap 5 12 ------------------------- | print s --------------------------------------60 | | ------------------------- ---------------------------- | | | | | Global m --------------------------CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | 60 | ----------------------------
Stack Heap 5 12 60 ------------------------- ---------------------------- | | | | | Global m --------------------------CODE | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | 60 | ----------------------------
back at global frame. There is no more code. Global frame dies.
Stack Heap --------------------------- | unix> python demo.py | | 60 | ----------------------------
Game over.
Stack Heap ------------------------- ---------------------------- | | | | | Global | | | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------
Stack Heap ------------------------- ---------------------------- | | | | | Global | | | | | | | ------------------------- | | Command Window ----------------------------- --------------------------- | unix> python demo.py | | | ----------------------------