Lecture 9: Memory in Python
CS 1110 Introduction to Computing Using Python
[E. Andersen, A. Bracy, D. Gries, L. Lee, S. Marschner, C. Van Loan, W. White]
http://www.cs.cornell.edu/courses/cs1110/2018sp
Lecture 9: Memory in Python CS 1110 Introduction to Computing - - PowerPoint PPT Presentation
http://www.cs.cornell.edu/courses/cs1110/2018sp Lecture 9: Memory in Python CS 1110 Introduction to Computing Using Python [E. Andersen, A. Bracy, D. Gries, L. Lee, S. Marschner, C. Van Loan, W. White] Feb 27: CS 1110: Announcements Last
CS 1110 Introduction to Computing Using Python
[E. Andersen, A. Bracy, D. Gries, L. Lee, S. Marschner, C. Van Loan, W. White]
http://www.cs.cornell.edu/courses/cs1110/2018sp
Feb 27: CS 1110: Announcements
§ CMS: OPTIONAL: one-on-ones
1st, 11:59pm to register a conflict or a need for accommodation. There is no single makeup
§ CMS: Prelim 1 conflicts
11:59pm.
Storage in Python – Round 1
§ What you “start with” § Stores global variables § Lasts until you quit Python
id2
p Global Space
Folders Live on the Heap
p = shapes.Point3(1,2,3) id5
p
id5 Point3
Heap Space Global Space
1 x 2 y 3 z
p lives in the Global Space. Its folder lives on the Heap.
Storage in Python – Round 2
§ What you “start with” § Stores global variables § Lasts until you quit Python
§ Where “folders” are stored § Have to access indirectly
id2
p Global Space id2 Heap Space
Calling a Function Creates a Call Frame
p = shapes.Point3(1,2,3) incr_x(p) id5
p
id5 Point3
Heap Space Global Space
1 x 2 y 3 z
Call Frame incr_x
1
id5 the_point
What goes in a Call Frame?
p = shapes.Point3(1,2,3) def incr_x(the_point): the_point.x = the_point.x+1 incr_x(p) id5
p
Global Space Call Frame incr_x
1
id5 the_point
(1) Boxes for parameters at the start of the function (2) Boxes for variables local to the function as they are created
Storage in Python – Round 3
§ What you “start with” § Stores global variables § Lasts until you quit Python
§ Where “folders” are stored § Have to access indirectly
§ Parameters § Other variables local to function § Lasts until function returns
id2
p Global Space id2 Heap Space f1 f2 Call Frames
Frames and Helper Functions
places? Or code that accomplishes some conceptual sub-task? Write a helper function! Makes your code easier to:
§ Read § Write § Edit § Debug
9
From before: last_name_first
def last_name_first(n): """Returns: copy of <n> but in the form <last-name>, <first-name> Precondition: <n> is in the form <first-name> <last-name> with one or more blanks between the two names. """ space_index = n.find(' ') first = n[:space_index] last = n[space_index+1:].strip() return last+', '+first
Murakami, Haruki'
1 2 3 4
10
Frames and Helper Functions
def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end] def last_name(s): """Prec: see last_name_first""" end = s.rfind(' ') return s[end+1:]
11
4 5 6 7 rfind gets the last instance of substring def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first 1 2 3
Drawing Frames for Helper Functions (1)
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
12
1 2 3 4 5
last_name_first 1 'Haruki Murakami'
s
last_name_first('Haruki Murakami')
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
13
1 2 3
last_name_first 1
s
first_name 'Haruki Murakami'
s
4
4 5
'Haruki Murakami'
Not done. Do not erase!
Drawing Frames for Helper Functions (2)
last_name_first('Haruki Murakami')
Drawing Frames for Helper Functions (3)
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
14
1 2 3
last_name_first 1
s
first_name
s end
6 5
4 5
'Haruki Murakami' 'Haruki Murakami'
last_name_first('Haruki Murakami')
Drawing Frames for Helper Functions (4)
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
15
last_name_first 1
1 2 3
s
first_name
s end
6 RETURN 'Haruki'
4 5
'Haruki Murakami' 'Haruki Murakami'
last_name_first('Haruki Murakami')
B:
Question: What Happens Next?
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
last_name_first 1
1 2 3
s
first_name
s end
6 RETURN 'Haruki'
4 5
'Haruki Murakami' 'Haruki Murakami' last_name_first 2
Stuff
A:
ERASE FRAME #2
C: ERASE FRAME #1
ERASE FRAME #2 first_name
Stuff
last_name_first 2
Stuff
last_name_first('Haruki Murakami')
B:
Answer: What Happens Next?
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + ',' + first def first_name(s): """Prec: see last_name_first""" end = s.find(' ') return s[0:end]
last_name_first 1
1 2 3
s
first_name
s end
6 RETURN 'Haruki'
4 5
'Haruki Murakami' 'Haruki Murakami' last_name_first 2
Stuff
A:
ERASE FRAME #2
C: ERASE FRAME #1
ERASE FRAME #2 first_name
Stuff
last_name_first 2
Stuff
Drawing Frames for Helper Functions (5)
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + '.' + first def last_name(s): """Prec: see last_name_first""" end = s.rfind(' ') return s[end+1:] 1 2 3
last_name_first 2
s first
6 7
'Haruki Murakami' 'Haruki'
last_name_first('Haruki Murakami')
Drawing Frames for Helper Functions (6)
def last_name_first(s): """Precondition: s in the form <first-name> <last-name>""" first = first_name(s) last = last_name(s) return last + '.' + first def last_name(s): """Prec: see last_name_first""" end = s.rfind(' ') return s[end+1:]
19
1 2 3
last_name_first 2
s
last_name
s first
6
6 7
'Haruki Murakami' 'Haruki' 'Haruki Murakami'
last_name_first('Haruki Murakami')
The Call Stack
§ Cannot remove one above w/o removing one below
stack in memory
§ Error if it cannot hold stack (“stack overflow”)
20
function1
calls calls calls calls
function2 function3 function4 function5
Call Stack Example (1)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Call Frame Stack
Call Stack Example (2)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() basic_line 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 11
Call Frame Stack
Call Stack Example (3)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() basic_line happy_birthday 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 11
Call Frame Stack
Call Stack Example (4)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday basic_line happy_birthday
RETURN
None 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 11
Call Frame Stack
Call Stack Example (5)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday basic_line 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 12
Call Frame Stack
Call Stack Example (6)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday basic_line to_you 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 12
Call Frame Stack
Call Stack Example (7)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday to you basic_line to_you
RETURN
None 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14 12
Call Frame Stack
Call Stack Example (8)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday to you basic_line
RETURN
None 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 14
Call Frame Stack
Call Stack Example (9)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday to you 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 15
Call Frame Stack
Call Stack Example (9)
song def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear James”) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() Happy Birthday to you basic_line 11 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 15
Call Frame Stack
31
Errors and the Call Stack
def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear ”+name) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Happy Birthday to you Happy Birthday to you Happy Birthday Traceback (most recent call last): File "birthday_error.py", line 18, in <module> song() File "birthday_error.py", line 16, in song line_with_name() File "birthday_error.py", line 9, in line_with_name dear() File "birthday_error.py", line 4, in dear print("Dear "+name) NameError: name 'name' is not defined
Make sure you can see line numbers in Komodo. Preferences è Editor
32
Errors and the Call Stack, in Color!
def happy_birthday(): print(“Happy Birthday”) def dear(): print(“Dear ”+name) def to_you(): print(“to you”) def line_with_name(): happy_birthday() dear() def basic_line(): happy_birthday() to_you() def song(): basic_line() basic_line() line_with_name() basic_line() song() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Happy Birthday to you Happy Birthday to you Happy Birthday Traceback (most recent call last): File "birthday_error.py", line 18, in <module> song() File "birthday_error.py", line 16, in song line_with_name() File "birthday_error.py", line 9, in line_with_name dear() File "birthday_error.py", line 4, in dear print("Dear "+name) NameError: name 'name' is not defined
Where error was found Script code. Global space
33
Functions and Global Space
A function definition
INCHES_PER_FT = 12 def get_feet(ht_in_inches): return ht_in_inches // INCHES_PER_FT Global Space 12 INCHES_PER_FT
See for yourself: https://tinyurl.com/get-feet
id6 get_feet id6
Body
function
Heap Space
Body
Function Definition vs. Call Frame
34
Global Space Call Frame (memory for function call goes here) It’s alive! Heap Space (Function definition goes here)
Modules and Global Space
import math
35
id5 math id5
module
import
pi 3.141592 e 2.718281 functions
Heap Space Global Space
Modules, Objects, Call Frames (1)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python knows there is a shapes module And it knows where to find it (à on the Heap).
Heap Space Global Space
Modules, Objects, Call Frames (2)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python knows there is a function called incr_x And it knows where to find the definition (à on the Heap).
Heap Space Global Space
Modules, Objects, Call Frames (3)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python just created a point p. p lives in the Global Space. Its folder lives on the Heap.
Heap Space Global Space
Modules, Objects, Call Frames (4)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python just created a call frame for the function incr_x Parameter pt lives in the call frame. Its value is whatever the argument to incr_x was.
Call Frame Heap Space Global Space
Modules, Objects, Call Frames (5)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python is about to execute the first instruction in the function incr_x
Call Frame Heap Space Global Space
Modules, Objects, Call Frames (6)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python just executed the lone instruction in the function incr_x. Since there is no return statement, the return value of NONE is created in the call frame.
Call Frame Heap Space Global Space
Modules, Objects, Call Frames (7)
import shapes def incr_x(pt): pt.x = pt.x+1 p = shapes.Point3(1,2,3) incr_x(p)
Narration: Python just returned from the function incr_x. Its call frame is destroyed because the function is done.
Heap Space Global Space
Storage in Python (Final Version!)
id2
p id2 f1 f2
§ What you “start with” § Stores global variables, modules & functions § Lasts until you quit Python
§ Where “folders” are stored § Have to access indirectly
§ Parameters § Other variables local to function § Lasts until function returns
Heap Space Global Space Call Frame Stack
45
Global & Local Variables
print("Welcome to the Star Wars Name Generator!") print("Inputs must be 3 letters or longer. What is your...") first = input("...First name? ") middle = input("...Middle name? ") last = input("...Last name? ") town = input("...Hometown? ") def make_name(name1, name2): name = name1[0:3]+name2[0:3].lower() return name new_first = make_name(first, last) new_last = make_name(middle, town) print("Your Star Wars name is: "+new_first+" "+new_last)
46
Global & Local Variables
print("Welcome to the Star Wars Name Generator!") print("Inputs must be 3 letters or longer. What is your...") first = input("...First name? ") middle = input("...Middle name? ") last = input("...Last name? ") town = input("...Hometown? ") def make_name(name1, name2): name = name1[0:3]+name2[0:3].lower() return name new_first = make_name(first, last) new_last = make_name(middle, town) print("Your Star Wars name is: "+new_first+" "+new_last)
Question: What if these parameters were called first & last?
47
Global & Local Variables
print("Welcome to the Star Wars Name Generator!") print("Inputs must be 3 letters or longer. What is your...") first = input("...First name? ") middle = input("...Middle name? ") last = input("...Last name? ") town = input("...Hometown? ") def make_name(name1, name2): name = name1[0:3]+name2[0:3].lower() return name new_first = make_name(first, last) new_last = make_name(middle, town) print("Your Star Wars name is: "+new_first+" "+new_last)
Question: What if this variable were called first?