the last cs lecture you’ll ever need! on warner brothers' insistence, we affirm that this...

113
The last CS lecture you’ll ever need! On Warner Brothers' insistence, we affirm that this 'C' does not stand for 'Chamber' and 'S' does not stand for 'Secrets.' * Caution: do not take this statement too literally or it is possible find yourself in twice as many CS lectures as you need! Aye! Aye! Aye! mateys… Our legal counsel requires us to include these footnotes… Hw #1 due this Thursday, 9/17, at 11:59 pm CS? This is just like magic! * No class, Wed. September 23, 2009 (DC) Hw #0 due this Thursday, 9/10, at 11:59 pm IS 313 Today!

Upload: clement-miller

Post on 03-Jan-2016

216 views

Category:

Documents


0 download

TRANSCRIPT

The last CS lecture you’ll ever need!

On Warner Brothers' insistence, we affirm that this 'C' does not stand for 'Chamber' and 'S' does not stand for 'Secrets.'

*

Caution: do not take this statement too literally or it is possible find yourself in twice as many CS lectures as you need!

Aye! Aye! Aye! mateys…

Our legal counsel requires us to include these footnotes…

Hw #1 due this Thursday, 9/17, at 11:59 pm

CS? This is just like magic!

*

No class, Wed. September 23, 2009 (DC)

Hw #0 due this Thursday, 9/10, at 11:59 pm

IS 313 Today!

Looking back…

Picobot!?

Python?!

Guido van Rossum

Python testimonials

20 years ago…

What is it?

What type is it?

Computation's Double Identity

name: xtype: intLOC: 300

41

"variables as containers"

memory location 300

Computation Data

name: ytype: intLOC: 304

42

memory location 304

Python Data Types

bool

int

long

float 3.14

10**100

42

TrueFalse

Numeric

Name Example What is it?

values with a fractional part

integers > 2147483647

integers <= 2147483647

the results from a comparison:

==, !=, <, >, <=, >= "Boolean value"

Datatypes as genes…

bool

Dominant

int

long

float

Recessive41 + True

10**100 - 10**100

1.0 / 5

1 / 5

What will these results be?

Python Operato

rs

I’d go with parentheses over precedence

Precedence

*

%

**

/

>

<

==

+

-

Caution Level

=Highest

Lowest

**

* %/

> < ==

+ -

=

-

( )

( )

It's not worth remembering all these %+/* things!

remainder

power

is equal to

set equal to

divide

as usual

7 % 3

% the "mod" operator

8 % 3

9 % 3

16 % 7

x%4 == 0

x%2 == 0

For what values of x are these

True?What happens on these

years?

x%y returns the remainder when x is divided by y

x%2 == 1

the "equals" operators

= != ==What about === ?

= Names Data

Aiden, Braden, Kaden…?

Ava, Abigail, Caylin…?

Choosing the right

name is more importantthan I thought.

>> x = 41

>> y = x + 1

Inside the machine…

x = 41

y = x + 1

name: xtype: intLOC: 300

41

What is happening behind the scenes:

What's happening in python:

"variables as containers"

memory location 300

id, delComputation Data Storage

name: ytype: intLOC: 312

42

memory location 312

Computer Memory

Random Access Memory (RAM)

byte = 8 bits

word = 4 bytes = 32 bits

is a long list of memory locationsbit = 1 "bucket" of charge

name: ytype: intLOC: 312

4 bytes for an int

on or off

is it really a coincidence that this looks like the string theory picture??

42

plus overhead…

Re-naming…!

Aiden, Aiden, Aiden, Aiden,

Aiden, …

It's possible to lose your name in Python!

>> x = 41

>> y = x + 1

>> x

41

>> y

42

>> x = x + y

>> x

??

>> y

??

Are numbers enough?

No!

You need lists of numbers, as well!

and strings are helpful, too.

list

str

These are Python sequences…

Can all information be represented using

lists ?

Networks

Images/Video

Sounds/Speech

{ 2, 3, 5, 7, 11 }

Data and lists?

‘Many years later, as he faced the firing squad, Colonel Aureliano Buendia was to remember

that distant afternoon when his father took him to discover ice.’

Text

Sets

Ideas?

"sequences"

string functions

strlen+*

converts input to a string

returns the string’s length

str(42) returns '42'len('42') returns 2'XL' + 'II' returns 'XLII' 'VI'*7 returns 'VIVIVIVIVIVIVI'

concatenates strings

repeats strings

s1 = "ha"

s2 = "t"Given these strings

What did you say!?!

s1 + s2

2*s1 + s2 + 2*(s1+s2)

What are

String surgery

s[ ] indexes into the string, returning a one-character string

s = 'harvey mudd college'

s[0] returns 'h'

s[6] returns

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

s[ ] returns 'e' Which index returns 'e'?

python != English

s[len(s)] returns

Read "s-of-zero" or "s-zero"

index

Negative indices…

s = 'harvey mudd college'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

-1

-2

-3

-4

-5

-6

-7

-8

-9

-10

-11

-12

-13

-14

-15

-16

-17

-18

-19

Negative indices count backwards from the end!

s[-1] returns 'e'

s[-11] returns

s[-0] returns Python can

suit any mood…

s[ : ] slices the string, returning a substring

s[12:18] returns 'colleg'

s[0:6] returns 'harvey'

s = 'harvey mudd college'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Slicing

what to do if you want a bigger piece of the

pie!

What's going on here?

s[17:] returns 'ge'

s[:] returns 'harvey mudd college'

s[ : ] slices the string, returning a substring

s[12:18] returns 'colleg'

s[0:6] returns 'harvey'

s = 'harvey mudd college'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Slicing

what to do if you want a bigger piece of the

pie!

the first index is the first character of the slice

s[17:] returns 'ge'

the second index is ONE AFTER the last character

a missing index means the end of the string

s[:] returns 'harvey mudd college'

s[ : ] slices the string, returning a substring

s[15:-1]

s[1:]

s = 'harvey mudd college'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Slicing

what to do if you want a bigger piece of the

pie!

What are these slices

?How would you get

'mud'

'e' Don't 'wor' 'e'- Be 'hap' 'e' !

s[0:8:2] returns 'hre '

s[ : : ] skip-slices, returning a subsequence

s = 'harvey mudd college'0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

Skip-Slicing

if you don't want your neighbor to get

any…

the third index is the "stride" lengthit defaults to 1

'doe'

I love this one.

What skip-slice returns

What does this return?

s[1::6]

Lists ~ Strings of anything

L = [ 3.14, [2,40], 'third', 42 ]

Square brackets tell python you want a list.

len(L)

L[0]

L[0:1]

'hi'How could you extract from

L

Slicing: always returns the same type

Indexing: could return a different type

Commas separate elements.

Raising and razing lists

What are

"Quiz"pi = [3,1,4,1,5,9] Q = [ 'pi', "isn't", [4,2] ]

What slice of pi is [3,4,5]

message = 'You need parentheses for chemistry !'

What is message[::5]

What are

pi[0] * (pi[1] + pi[2])

and

pi[0] * (pi[1:2] + pi[2:3])

What is message[9:15]

What are

What slice of pi is [3,1,4]

Name(s):

Part 2Part 1Q[0]

Q[0:1]

Q[0][1]

Q[1][0]

I ( )

len(pi)

len(Q)

len(Q[1])

Raising and razing lists

What are

"Quiz"pi = [3,1,4,1,5,9] Q = [ 'pi', "isn't", [4,2] ]

What slice of pi is [3,4,5]

message = 'You need parentheses for chemistry !'

What is message[::5]

What are

pi[0] * (pi[1] + pi[2])

and

pi[0] * (pi[1:2] + pi[2:3])

What is message[9:15]

What are

What slice of pi is [3,1,4]

Name(s):

Part 2Part 1Q[0]

Q[0:1]

Q[0][1]

Q[1][0]

I ( )

len(pi)

len(Q)

len(Q[1])

Python slices… It dices...

… but wait, there's more!

>>> 3*'i' in 'alien'

False

The in thing

>>> 'i' in 'team'

False

>>> 'cs' in 'physics'

True

>>> 'sleep' not in 'CS 5'

True

>>> 42 in [41,42,43]

True

>>> 42 in [ [42], '42' ]

??

python is badly confused here…

but otherwise it seems pretty perceptive!

a little bit different for lists…

What’s out here?

Computation's Double Identity

name: xtype: intLOC: 300

41

"variables as containers"

memory location 300

Computation Data

name: ytype: intLOC: 304

42

memory location 304

the monomers are functions…

# my own function!

def dbl( x ):

""" returns double its input, x """

return 2*x

How functions look

Comments

Docstrings

(1) describes overall what the function does, and

(2) explains what the inputs mean/are

They become part of python's built-in help system! With each function be sure

to include one that

They begin with #

keywords

def starts the functionreturn stops it

immediately and sends back the return value

Some of Python's baggage…

Look good to me!

return != print

>>> answer = dbl(21)

def dbl(x):

""" doubles x """

return 2*x

def dblPR(x):

""" doubles x """

print 2*x

>>> answer = dbl(21)

return provides the function call's value …

print just prints

How functions act

>>> yours = undo('caf')

>>> mine = undo(undo('caf'))

def undo(s):

""" undo undoes its input!

input: s, any string

"""

return 'de' + s

strings, lists, numbers … all data are fair game

My brain has just hit recursophobic

collapse!

How functions work…

def f(x): return 11*g(x) + g(x/2)

What is >>> demo(-4) ?

def demo(x): return x + f(x)

def g(x): return -1 * x

This puts the fun in function!

Three functions:

"Quiz" Initials:The aliens have asked - very politely - that names be reasonably legible… Thank you!

How functions work…

def f(x): return 11*g(x) + g(x/2)

>>> demo(-4) ?

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

def g(x): return -1 * x

How functions work…

def f(x): return 11*g(x) + g(x/2)

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

fx = -4

return 11*g(x) + g(x/2)def g(x): return -1 * x

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

fx = -4

return 11*g(x) + g(x/2)def g(x): return -1 * x

These are different x's !

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

f

g

x = -4

return 11*g(-4) + g(-4/2)

x = -4

return -1.0 * x

def g(x): return -1 * x

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

f

g

x = -4

return 11* 4 + g(-4/2)

x = -4

return -1 * -4 4>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1.0 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

fx = -4

return 11* 4 + g(-4/2)

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

f

g

x = -4

return 11* 4 + g(-4/2)

x = -2

return -1 * -2 2>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1.0 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

fx = -4

return 11* 4 + 2

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1.0 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

fx = -4

return 11* 4 + 2 46

>>> demo(-4) ?

How functions work…

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1.0 * x

def demo(x): return x + f(x)

demox = -4

return -4 + 46

42>>> demo(-4)

42

Douglas Adams's 42 puzzleanswer: 42 question: unknown

Function stacking

def f(x): return 11*g(x) + g(x/2)

def g(x): return -1 * x

def demo(x): return x + f(x)

demox = -4

return -4 + f(-4)

f

g

x = -4

return 11* 4 + g(-4/2)

x = -2

return -1 * -2 2

"The stack"

(1) remembers separate functions' values for variables…(2) remembers where to send results back

to…

>>> demo(-4)

42

Function design

Thinking sequentially

5! = 5 * 4 * 3 * 2 * 1

N! = N * (N-1) * (N-2) * … * 3 * 2 * 1

factorial

5! = 120

Thinking sequentially

5! = 5 * 4 * 3 * 2 * 1

N! = N * (N-1) * (N-2) * … * 3 * 2 * 1

factorial

5! = 120

Next time & beyond…

Recursion == self-reference!

Thinking recursively

5! = 5 * 4 * 3 * 2 * 1

N! = N * (N-1) * (N-2) * … * 3 * 2 * 1

factorial

5! = 120

5! =

N! =

Warning

def fac(N): return N * fac(N-1)

This is legal code!

I wonder how this code will STACK up!?

def fac(N): return N * fac(N-1)

No base case -- the calls to fac will never stop!

Make sure you have a base case, then worry about the

recursive step...

Warning

def fac(N): return fac(N)

Roadsigns and recursion

examples of self-fulfilling danger

def fac(N):

if N <= 1: return 1

Thinking recursively !

Base Case

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

Base Case

Recursive Step

Thinking recursively !

Human: Base case and 1 step Computer: Everything else

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

>>> fac(1)

Result: 1 The base case is No Problem!

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

3 * fac(2)

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

3 * fac(2)

2 * fac(1)

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

3 * fac(2)

2 * fac(1)

1

"The Stack"

Remembers all of the individual calls to

fac

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

3 * fac(2)

2 * 1

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * fac(3)

3 * 2

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * fac(4)

4 * 6

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

5 * 24

Behind the curtain…

def fac(N):

if N <= 1: return 1

else: return N * fac(N-1)

fac(5)

Result: 120

0 N*** -> X 1

0 x*** -> N 0Look familiar?

Base Case

Recursive Step

Behind the curtain…

Let recursion do the work for you.

def fac(N):

if N <= 1: return 1 else: return N * fac(N-1)

You handle the base case – the easiest possible

case to think of!

Recursion does almost all of the rest of the problem!

Exploit self-similarity

Produce short, elegant code

Less work !

Let recursion do the work for you.

But you do need to do one step yourself…

def fac(N):

if N <= 1: return 1 else: return fac(N)

You handle the base case – the easiest possible

case to think of!

This will not work

Breaking Up…

…is easy to do with Python

s = "This has 2 T's"

How do we get at the initial character of s?

L = [ 42, 21, 7 ]

How do we get at the initial element of L?

How do we get at ALL THE REST of s?

How do we get at ALL the REST of L?

Recursion Examples

def mylen(s):

""" input: any string, s

output: the number of characters in s

"""

if :

else:

base case test!

Recursion Examples

def mylen(s):

""" input: any string, s

output: the number of characters in s

"""

if s == '':

return 0

else:

rest = s[1:]

len_of_rest = mylen( rest )

total_len = 1 + len_of_rest

return total_len

Recursion Examples

def mylen(s):

""" input: any string, s

output: the number of characters in s

"""

if s == '':

return 0

else:

rest = s[1:]

len_of_rest = mylen( rest )

return 1 + len_of_rest

Recursion Examples

def mylen(s):

""" input: any string, s

output: the number of characters in s

"""

if s == '':

return 0

else:

rest = s[1:]

return 1 + mylen( rest )

Recursion Examples

def mylen(s):

""" input: any string, s

output: the number of characters in s

"""

if s == '':

return 0

else:

return 1 + mylen(s[1:])There's not much len left here!

mylen('cs5')Behind the curtain…

Recursion Examples

def mymax(L):

""" input: a NONEMPTY list, L

output: L's maximum element

"""

if :

elif :

else:

base case test!

another case…

Recursion Examples

def mymax(L):

""" input: a NONEMPTY list, L

output: L's maximum element

"""

if len(L) == 1:

return L[0]

elif L[0] < L[1]:

return mymax( L[1:] )

else:

return mymax( L[0:1] + L[2:] ) Hey - do I get a

slice?!

mymax( [1,7,3,42,5] )Behind the curtain…

Recursion: not just numbers

Relationships

Self-similarity elsewhere...

Natural phenomena

Names / Acronyms

What is an “ancestor” ?

how much here is leaf vs. stem?

GNU == "GNU’s Not Unix"

Recursion: not just numbers

Relationships

Self-similarity elsewhere...

Natural phenomena

Names / Acronyms

What is an “ancestor” ?

GNU

all stem!

An ancestor is a parent OR an ancestor of a

parent…

== GNU’s Not Unix

Try it!def power(b,p):

""" returns b to the p power using recursion, not ** inputs: int b, int p output: a float"""

power(5,2) == 25.0

def sajak(s):

sajak('wheel of fortune') == 6

What seven-letter English word w maximizes sajak(w) ?

What about y? You decide…

""" returns the number of vowels in the input string, s"""

Want more Pat?

if :

if :

Base case test

elif

else:

Base case test

else:

Remember: bp == b * bp-1

def power(b,p): """ inputs: base b and power p (an int)

implements: b**p

"""

if p == 0:

return

else:

returnRecursion is

power!

behind the curtainpower(2,3)

def sajak(s):

Base case?when there are no letters,

there are ZERO vowels

if it is NOT a vowel, the answer is

Rec. step?

Look at the initial character.

if it IS a vowel, the answer is

def sajak(s):

Base case?when there are no letters,

there are ZERO vowels

if it is NOT a vowel, the answer is just the number of vowels in the rest of sRec. step?

Look at the initial character.

if it IS a vowel, the answer is 1 + the number of vowels in the rest of s

def sajak(s):

if s == '':

return 0

elif s[0]=='a' or s[0]=='e' or…

Checking for a vowel: Try #1

Base Case

def sajak(s):

if len(s) == 0:

return 0

elif s[0] in 'aeiou':

return 1 + sajak(s[1:])

else:

return sajak(s[1:])

if it is NOT a vowel, the answer is just the number of vowels in the

rest of s

if it IS a vowel, the answer is 1 + the number of vowels in the

rest of s

Base Case

Rec. Steps

sajak('eerier')behind the curtain

Good luck with Homework #0 and

#1 !

The key to understanding recursion is to first

understand recursion…- advice from one of last

year's students

crazy recursion…

Recursion is the root of all computation since it trades

description for time.- Alan Perlis

Recursion is the secret to all happiness in writing short, powerful functional programs!

Monty Hall

Let’s make a deal ’63-’86

Sept. 1990

inspiring the “Monty Hall paradox”

Problem #2: montyhall()

Write a program that plays the part of Monty…

while we're here…

import random

comp = random.choice( range(0,100) )

while True:

user = input('Your choice: ')

print user, '?'

if user == comp:

print 'Yes!'

break

else:

print 'No...'

"Quiz" on recursion

def power(b,p): def sajak(s):

sajak('wheel of fortune') == 6

What five-letter English word w maximizes sajak(w) ?

Names:

What about y? You decide…Handle negative values of p,

as well.

""" returns the number of vowels in the input string, s"""

""" returns b to the p power using recursion and not ** inputs: b and p are ints output: should be a float"""

Want more Pat?Want more power?

power(5,2) == 25.0

For example, power(5,-1) == 0.2 (or so)

Any real computing with strings/lists?

Some strings are more equal than others…

Our DNA's nucleotides:

DNA

http://genome.ucsc.edu/cgi-bin/hgGateway

AGCT

Genetic disease expression

CTG repeats

Myotonic Dystrophyneuromuscular weakness in the face/torso

in the 3' UTR (three prime untranslated region), a particular section of messenger RNA

DNA

"Christmas Tree cataracts"

Its computational basis

www.neuro.wustl.edu/neuromuscular/musdist/pe-eom.html#myd

One sequence-checking algorithm…

def check(geneseq): """ seeks evidence of Myo. Dys. """ if 'ctg'*50 in geneseq: return True else: return False

• Why problems might this algorithm run into?

• What if we hadn't discovered the CTG-repeats yet?

• Can we make this algorithm more concise?

• What information might we prefer to know?

checks if one string is contained in another

One sequence-checking algorithm…

def check(geneseq): """ seeks evidence of Myo. Dys. """ if 'ctg'*50 in geneseq: return 'Trouble' elif 'ctg'*500 in geneseq : return 'BIG Trouble' else: return "You're OK!"

• Will this work as a two-diagnosis system? Or is something awry?

One sequence-checking algorithm…

def check(geneseq): """ seeks evidence of Myo. Dys. """ if 'ctg'*500 in geneseq: return 'BIG Trouble' elif 'ctg'*50 in geneseq : return 'Trouble' else: return "You're OK!"

Feeling much better!

most constrained

least constrained

Any real computing with strings/lists?

Some strings are more equal than others…

Our DNA's nucleotides:

DNA

http://genome.ucsc.edu/cgi-bin/hgGateway

AGCT

Genetic disease expression

CTG repeats

Myotonic Dystrophyneuromuscular weakness in the face/torso

in the 3' UTR (three prime untranslated region), a particular section of messenger RNA

DNA

"Christmas Tree cataracts"

Its computational basis

www.neuro.wustl.edu/neuromuscular/musdist/pe-eom.html#myd

One sequence-checking algorithm…

def check(geneseq): """ seeks evidence of Myo. Dys. """ if 'ctg'*50 in geneseq: return True else: return False

• Why problems might this algorithm run into?

• What if we hadn't discovered the CTG-repeats yet?

• Can we make this algorithm more concise?

• What information might we prefer to know?

checks if one string is contained in another

Functioning in Python

Some basic, built-in functions:

abs

max

min

sum

range

round

bool

float

int

long

list

str

these change data from one type to another

absolute value

of lists

creates lists

only as accurately as it can!

help dirThese are the most important:

You call that a

language?!

Functioning in Python

Far more are available in separate files, or modules:

import math

math.sqrt( 1764 )

dir(math)

from math import *

pi

sin( pi/2 )

accesses math.py's functions

lists all of math.py's functions

same, but without typing math. all of the time…

help()help modules

Functioning in Python

This doesn't look quite right…

# my own function!

def dbl( x ):

""" returns double its input, x """

return 2x

Functioning in Python

# my own function!

def dbl( x ):

""" returns double its input, x """

return 2*x

# my own function!

def dbl( x ):

""" returns double its input, x """

return 2*x

Functioning in Python

Comments

Docstrings

(1) describes overall what the function does, and

(2) explains what the inputs mean/are

They become part of python's built-in help system! With each function be sure

to include one that

They begin with #

keywords

def starts the functionreturn stops it

immediately and sends back the return value

Some of Python's baggage…

Functioning in Python

>>> yours = undo('caf')

>>> mine = undo(undo('caf'))

def undo(s):

""" this "undoes" its input, s """

return 'de' + s

strings, lists, numbers … all data are fair game