46
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) 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 defhappy_birthday():

  • Upload
    leliem

  • View
    217

  • Download
    3

Embed Size (px)

Citation preview

Lecture 9: Memory in Python

CS 1110Introduction 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

• Last call for a one-on-one! § CMS: OPTIONAL: one-on-ones

• Prelim 1 is March 13. You have until March 1st, 11:59pm to register a conflict or a need for accommodation. There is no single makeup session. See website: “Assessment à Exams”§ CMS: Prelim 1 conflicts

• A1 Revisions: open from Mar 1st thru Mar 7, 11:59pm.

Storage in Python – Round 1• Global Space

§ What you “start with”§ Stores global variables§ Lasts until you quit Python

id2pGlobal Space

Folders Live on the Heap

p = shapes.Point3(1,2,3)

id5p id5Point3

Heap Space Global Space

1x 2y 3z

p lives in the Global Space. Its folder lives on the Heap.

Storage in Python – Round 2• Global Space

§ What you “start with”§ Stores global variables§ Lasts until you quit Python

• Heap Space§ Where “folders” are stored§ Have to access indirectly

id2pGlobal Space

id2Heap Space

Calling a Function Creates a Call Frame

p = shapes.Point3(1,2,3)incr_x(p)

id5p id5Point3

Heap Space Global Space

1x 2y 3zCall Frame

incr_x 1

id5the_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)

id5pGlobal Space

Call Frame

incr_x 1

id5the_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• Global Space

§ What you “start with”§ Stores global variables§ Lasts until you quit Python

• Heap Space§ Where “folders” are stored§ Have to access indirectly

• Call Frames§ Parameters§ Other variables local to function§ Lasts until function returns

id2pGlobal Space

id2Heap Space

f1

f2Ca

ll Fr

ames

Frames and Helper Functions

• Functions can call each other!• Each call creates a new call frame• Writing the same several lines of code in 2

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

• last_name_first('Haruki Murakami') gives 'Murakami, Haruki'• last_name_first('Haruki Murakami') gives ' Murakami, Haruki'

1234

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

45

67

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

123

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

123

45

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

123

last_name_first 1

s

first_name

'Haruki Murakami's

4

45

'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

123

last_name_first 1

s

first_name

s

end 6

5

45

'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

123

s

first_name

s

end 6

RETURN 'Haruki'

45

'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

123

s

first_name

s

end 6

RETURN 'Haruki'

45

'Haruki Murakami'

'Haruki Murakami'last_name_first 2

Stuff

A:

ERASE FRAME #2

C: ERASE FRAME #1ERASE 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

123

s

first_name

s

end 6

RETURN 'Haruki'

45

'Haruki Murakami'

'Haruki Murakami'last_name_first 2

Stuff

A:

ERASE FRAME #2

C: ERASE FRAME #1ERASE FRAME #2

first_name

Stuff

last_name_first 2

Stuff

last_name_first('Haruki Murakami')

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:]

123

last_name_first 2

s

first

67

'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

123

last_name_first 2

s

last_name

s

first

6

67

'Haruki Murakami'

'Haruki'

'Haruki Murakami'

last_name_first('Haruki Murakami')

The Call Stack• Functions frames are “stacked”

§ Cannot remove one above w/o removing one below

• Python must keep the entire stack in memory§ Error if it cannot hold stack

(“stack overflow”)

20

function1calls

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

123456789101112131415161718

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

123456789101112131415161718

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

123456789101112131415161718

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_birthdayRETURN None

123456789101112131415161718

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

123456789101112131415161718

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

123456789101112131415161718

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 Birthdayto you

basic_line

to_youRETURN None

123456789101112131415161718

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 Birthdayto you

basic_lineRETURN None

123456789101112131415161718

14Call 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 Birthdayto you

123456789101112131415161718

15Call 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 Birthdayto you

basic_line 11

123456789101112131415161718

15Call Frame Stack

31

Errors and the Call Stackdef 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()

123456789101112131415161718

Happy Birthdayto youHappy Birthdayto youHappy BirthdayTraceback (most recent call last):File "birthday_error.py", line 18, in <module>song()

File "birthday_error.py", line 16, in songline_with_name()

File "birthday_error.py", line 9, in line_with_namedear()

File "birthday_error.py", line 4, in dearprint("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()

123456789101112131415161718

Happy Birthdayto youHappy Birthdayto youHappy BirthdayTraceback (most recent call last):File "birthday_error.py", line 18, in <module>song()

File "birthday_error.py", line 16, in songline_with_name()

File "birthday_error.py", line 9, in line_with_namedear()

File "birthday_error.py", line 4, in dearprint("Dear "+name)

NameError: name 'name' is not defined

Where error was found

Script code.Global space

33

Functions and Global SpaceA function definition• Creates a global variable (same name as function)• Creates a folder for body• Puts folder id in variable

INCHES_PER_FT = 12def get_feet(ht_in_inches):

return ht_in_inches // INCHES_PER_FT

Global Space

12INCHES_PER_FT

See for yourself: https://tinyurl.com/get-feet

id6get_feet

id6

Bodyfunction

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

id5math id5module

import• Creates a global variable (same name as module)

• Puts variables, functions in a folder

• Puts folder id in variable

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 moduleAnd 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_xAnd 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_xParameter pt lives in the call frame. Its value is whateverthe 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. Itscall frame is destroyed because the function is done.

Heap Space Global Space

Storage in Python (Final Version!)

id2p id2

f1

f2

• Global Space§ What you “start with”§ Stores global variables, modules & functions§ Lasts until you quit Python

• Heap Space§ Where “folders” are stored§ Have to access indirectly

• Call Frame Stack§ Parameters§ Other variables local to function§ Lasts until function returns

Heap Space Global Space

Call

Fram

e St

ack

45

Global & Local Variablesprint("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 Variablesprint("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 Variablesprint("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?