SlideShare a Scribd company logo
1 of 81
Download to read offline
Python Puzzlers
Feb 17, 2016
Nandan Sawant, Ryan Rueth
1. Defaulter
Defaulter
def extend_list(val, l=[]):
l.append(val)
return l
list1 = extend_list(10)
list2 = extend_list(123,[])
list3 = extend_list('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
Defaulter
def extend_list(val, l=[]):
l.append(val)
return l
list1 = extend_list(10)
list2 = extend_list(123,[])
list3 = extend_list('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
Defaulter
From the python documentation:
https://docs.python.org/2/reference/compound_stmts.html#function-definitions
● Avoid mutable default arguments
● If you use mutable default arguments,
○ don’t mutate them
○ have a good reason to mutate them (e.g. caching)
Defaulter
def extend_list(val, l=None):
if l is None:
l = []
l.append(val)
return l
list1 = extend_list(10)
list2 = extend_list(123,[])
list3 = extend_list('a')
print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3
list1 = [10]
list2 = [123]
list3 = ['a']
2. Who’s late?
Who’s late?
multipliers = [lambda x: (i+1)*x for i in range(10)]
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
Who’s late?
multipliers = [lambda x: (i+1)*x for i in range(10)]
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
[20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
Who’s late?
multipliers = []
for i in range(10):
def multiplier(x):
return (i+1) * x
multipliers.append(multiplier)
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
Who’s late?
multipliers = []
for i in range(10):
def multiplier(x):
return (i+1) * x
multipliers.append(multiplier)
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
[20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
● A closure occurs when a function has access to a local variable from
an enclosing scope that has finished its execution
● Closures in python are late-binding
● This means that the values of variables used in closures are looked
up at the time the closure is called
● This behavior is NOT specific to lambdas
Who’s late?
Who’s late?
multipliers = [lambda x, i=i: (i+1)*x for i in range(10)]
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Who’s late?
from functools import partial
from operator import mul
multipliers = [partial(mul, i+1) for i in range(10)]
def print_multiplication_table_for(number):
print [multiplier(number) for multiplier in multipliers]
print_multiplication_table_for(2)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
3. Western Addition
Western Addition (A)
Western Addition (A)
a = b = [1,2,3]
a += [4]
print a, b
a = a + [5]
print a, b
Western Addition (A)
a = b = [1,2,3]
a += [4]
print a, b
a = a + [5]
print a, b
[1, 2, 3, 4] [1, 2, 3, 4]
[1, 2, 3, 4, 5] [1, 2, 3, 4]
● a + b uses __add__ while a += b uses __iadd__
● An object's __add__ method is regular addition: it takes two
parameters, returns their sum, and doesn't modify either parameter
● An object's __iadd__ method also takes two parameters, but makes
the change in-place, modifying the contents of the first parameter
Western Addition (A)
Western Addition (B)
Western Addition (B)
a = b = 'western'
a += 'addition'
print a, b
a = a + 'sf'
print a, b
Western Addition (B)
a = b = 'western'
a += 'addition'
print a, b
a = a + 'sf'
print a, b
westernaddition western
westernadditionsf western
● a + b uses __add__ while a += b uses __iadd__, if it exists
● An object's __add__ method is regular addition: it takes two
parameters, returns their sum, and doesn't modify either parameter
● An object's __iadd__ method also takes two parameters, but makes
the change in-place, modifying the contents of the first parameter
● Because this requires object mutation, immutable types (like
Strings!) don’t have an __iadd__ method
Western Addition (B)
Western Addition (C)
Western Addition (C)
a = ([1,2,3],)
a[0] += [4]
print a
Western Addition (C)
a = ([1,2,3],)
a[0] += [4]
print a
TypeError: 'tuple' object does
not support item assignment
([1, 2, 3, 4],)
● An object's __iadd__ method takes two parameters, but makes the
change in-place, modifying the contents of the first parameter and
returns the first parameter
● The code above is equivalent to:
Western Addition (C)
a = ([1,2,3],)
x = a[0]
x = x.__iadd__([4]) # returns x itself
a[0] = x
Western Addition (D)
Western Addition (D)
a = b = 500
print a is b
a -= 200
b -= 200
print a is b
a = a - 200
b = b - 200
print a is b
--a
--b
print a is b
Western Addition (D)
a = b = 500
print a is b
a -= 200
b -= 200
print a is b
a = a - 200
b = b - 200
print a is b
--a
--b
print a is b
True
False
True
True
From the python documentation:
https://docs.python.org/2/c-api/int.html
Western Addition (D)
● There is no decrement (--) operator in python
● -- is simply two negation operators
4. Crossing the Boundary
Crossing the Boundary (A)
Crossing the Boundary (A)
a, b = 0, 1
def fib(n):
for i in range(n):
a, b = b, a + b
return a
print fib(4)
Crossing the Boundary (A)
a, b = 0, 1
def fib(n):
for i in range(n):
a, b = b, a + b
return a
print fib(4)
UnboundLocalError: local
variable 'b' referenced before
assignment
Crossing the Boundary (A)
x = 1
def f1():
print x
f1()
print x
x = 1
def f2():
x = 2
print x
f2()
print x
x = 1
def f3():
print x
x = 3
f3()
print x
Crossing the Boundary (A)
x = 1
def f1():
print x
f1()
print x
x = 1
def f2():
x = 2
print x
f2()
print x
x = 1
def f3():
print x
x = 3
f3()
print x
1
1
2
1
UnboundLocalError: local
variable 'x' referenced
before assignment
1
● If we want to access a global variable from inside a function, it is
possible
● The assignment statement inside a function creates variables in the
local scope
● If a local variable has the same name as a global variable the local
variable will always take precedence
● The assignment inside the function does not modify the global
variable
● We may not refer to both a global variable and a local variable by
the same name inside the same function, it gives us an error
● Deep Dive http://eli.thegreenplace.net/2011/05/15/understanding-unboundlocalerror-in-python
Crossing the Boundary (A)
Crossing the Boundary (A)
a, b = 0, 1
def fib(n):
for i in range(n):
global a, b
a, b = b, a + b
return a
print fib(4) 3
Crossing the Boundary (B)
Crossing the Boundary (B)
Crossing the Boundary (B)
Crossing the Boundary (C)
Crossing the Boundary (C)
main.py
try:
import quitter
except:
exit(0)
quitter.quit()
quitter.py
def quit():
exit(0)
# Add one indented line here
# to make main.py crash
python main.py
Crossing the Boundary (C)
main.py
try:
import quitter
except:
exit(0)
quitter.quit()
quitter.py
def quit():
exit(0)
exit = None
python main.py
Crossing the Boundary (C)
main.py
try:
import quitter
except:
exit(0)
quitter.quit()
quitter.py
def quit():
exit(0)
exit = None
UnboundLocalError: local variable
'exit' referenced before assignment
python main.py
5. Kids These Days
Kids These Days (A)
Kids These Days (A)
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x
Kids These Days (A)
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x
1 1 1
1 2 1
3 2 3
● In Python, class variables are internally handled as dictionaries.
● If a variable name is not found in the dictionary of the current class,
the class hierarchy (i.e., its parent classes) are searched until the
referenced variable name is found
● If the referenced variable name is not found in the class itself or
anywhere in its hierarchy, an AttributeError occurs
Kids These Days (A)
Kids These Days (B)
Kids These Days (B)
class Parent:
x = 1
class Child1(Parent):
pass
class Child2(Parent):
x = 2
class GrandChild(Child1, Child2):
pass
print GrandChild.x
Kids These Days (B)
class Parent:
x = 1
class Child1(Parent):
pass
class Child2(Parent):
x = 2
class GrandChild(Child1, Child2):
pass
print GrandChild.x 1
Kids These Days (B)
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
x = 2
class GrandChild(Child1, Child2):
pass
print GrandChild.x 2
● If you don’t inherit from ‘object’, you’re defining an old style class
● MRO is Method Resolution Order. Lookup __mro__
● MRO for old style classes follows a native DFS approach
Grandchild -> Child 1 -> Parent -> Child 2 -> Parent
● MRO for new style classes is more sensible
Grandchild -> Child 1 -> Child 2 -> Parent
● Don’t use old-style classes
Kids These Days (B)
6. Exceptional Circumstances
Exceptional Circumstances
user_id = 'a'
try:
user_id = int(user_id)
print user_id
except TypeError, ValueError:
print "Oops!"
(a) a
(b) 65
(c) Oops!
(d) raises TypeError
(e) raises ValueError
Exceptional Circumstances
user_id = 'a'
try:
user_id = int(user_id)
print user_id
except TypeError, ValueError:
print "Oops!"
(a) a
(b) 65
(c) Oops!
(d) raises TypeError
(e) raises ValueError
ValueError: invalid literal
for int() with base 10: 'a'
Exceptional Circumstances
user_id = 'a'
try:
user_id = int(user_id)
print user_id
except (TypeError, ValueError):
print "Oops!"
(a) a
(b) 65
(c) Oops!
(d) raises TypeError
(e) raises ValueError
● If you’re catching multiple exceptions in python 2.x,
you must enclose them in parentheses
● If you do not, the second argument to except is treated as a
reference to the exception object. E.g. this may look familiar:
except Exception, e
● This problem goes away in python 3.x as
except Exception, e
is not a valid syntax. It is replaced by
except Exception as e
Exceptional Circumstances
7. So long!
So long!
x = set([type(1), type(1L), type(1.0)])
y = set([1.__class__, 1L.__class__, 1.0.__class__])
print x == y
(a) True
(b) False
(c) TypeError
(d) None of the above
So long!
x = set([type(1), type(1L), type(1.0)])
y = set([1.__class__, 1L.__class__, 1.0.__class__])
print x == y
(a) True
(b) False
(c) TypeError
(d) None of the above
y = set([1.__class__, 1L.__class__, 1.0.__class__])
^
SyntaxError: invalid syntax
It is a tokenization issue!
The . is parsed as the beginning of the fractional part of a floating point
number. When it encounters something other than a number, it will
throw an error.
So long!
So long!
x = set([type(1), type(1L), type(1.0)])
y = set([(1).__class__, 1L.__class__, 1.0.__class__])
print x == y
(a) True
(b) False
(c) TypeError
(d) None of the above
8. Zilch
Zilch
z = False
i = []
l = 0,
c = None
h = {}
print any((z, i, l, c, h))
(a) True
(b) False
(c) (False, False, False, False, False)
(d) None of the above
Zilch
z = False
i = []
l = 0,
c = None
h = {}
print any((z, i, l, c, h))
(a) True
(b) False
(c) (False, False, False, False, False)
(d) None of the above
Zilch
z = False
i = []
l = 0,
c = None
h = {}
print any((z, i, l, c, h))
(a) True
(b) False
(c) (False, False, False, False, False)
(d) None of the above
When creating a tuple, in all cases except the empty tuple, the comma
is the important thing.
Parentheses are only required for other syntactic reasons: to distinguish
a tuple from a set of function arguments, operator precedence, or to
allow line breaks.
Zilch
https://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences
9. It’s 2016!
It’s 2016!
print 2,016 * 2,016
(a) 4064256
(b) 4,064,256
(c) 4 256
(d) 2 32 16
(e) None of the above
It’s 2016!
print 2,016 * 2,016
(a) 4064256
(b) 4,064,256
(c) 4 256
(d) 2 32 16
(e) None of the above
2 28 14
The 0 is an outdated prefix that Python 2.x uses
to represent Octal numbers.
In Python 3, you must write: 0o16 instead.
It’s 2016!
10. Finally
Finally
def find_inverse(n):
inverse = 1
try:
inverse = 1 / k
finally:
return inverse
fi = find_inverse
print fi(-1) + fi(0) + fi(1)
(a) 0
(b) 1
(c) 3
(d) raises ZeroDivisionError
(e) raises NameError
(f) None of the above
Finally
def find_inverse(n):
inverse = 1
try:
inverse = 1 / k
finally:
return inverse
fi = find_inverse
print fi(-1) + fi(0) + fi(1)
(a) 0
(b) 1
(c) 3
(d) raises ZeroDivisionError
(e) raises NameError
(f) None of the above
Finally
return in finally will swallow the actual return value in the try block
return in finally will swallow the exception
Finally
References
● How to format code within a presentation
● Python Puzzlers by Tendayi Mawushe at PyCon Ireland 2010
● Python Puzzlers by Alan Pierce at Khan Academy
● Python Epiphanies by Stuart Williams at PyCon Montreal 2015
● Python Interview Questions
● Python Gotchas
● Raymon Hettinger’s twitter feed @raymondh

More Related Content

What's hot

Functions in python
Functions in pythonFunctions in python
Functions in python
Ilian Iliev
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
Mario Fusco
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
HCMUTE
 

What's hot (20)

13. Java text processing
13.  Java text processing13.  Java text processing
13. Java text processing
 
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
 
Introduction to Python and TensorFlow
Introduction to Python and TensorFlowIntroduction to Python and TensorFlow
Introduction to Python and TensorFlow
 
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
 
Functions in python
Functions in pythonFunctions in python
Functions in python
 
Python
PythonPython
Python
 
Logic programming a ruby perspective
Logic programming a ruby perspectiveLogic programming a ruby perspective
Logic programming a ruby perspective
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
Python Tutorial
Python TutorialPython Tutorial
Python Tutorial
 
07. Java Array, Set and Maps
07.  Java Array, Set and Maps07.  Java Array, Set and Maps
07. Java Array, Set and Maps
 
Learn python in 20 minutes
Learn python in 20 minutesLearn python in 20 minutes
Learn python in 20 minutes
 
16. Java stacks and queues
16. Java stacks and queues16. Java stacks and queues
16. Java stacks and queues
 
Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fu
 
Python 표준 라이브러리
Python 표준 라이브러리Python 표준 라이브러리
Python 표준 라이브러리
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Python Modules, Packages and Libraries
Python Modules, Packages and LibrariesPython Modules, Packages and Libraries
Python Modules, Packages and Libraries
 
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCEFUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative Practice
 
DISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in JavaDISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in Java
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
 

Viewers also liked

Viewers also liked (10)

Inro to Secure Sockets Layer: SSL
Inro to Secure Sockets Layer: SSLInro to Secure Sockets Layer: SSL
Inro to Secure Sockets Layer: SSL
 
Intro to Python Programming Language
Intro to Python Programming LanguageIntro to Python Programming Language
Intro to Python Programming Language
 
Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)
 
Object-oriented Programming in Python
Object-oriented Programming in PythonObject-oriented Programming in Python
Object-oriented Programming in Python
 
Python Advanced – Building on the foundation
Python Advanced – Building on the foundationPython Advanced – Building on the foundation
Python Advanced – Building on the foundation
 
Python Programming Language
Python Programming LanguagePython Programming Language
Python Programming Language
 
Introduction to Python
Introduction to Python Introduction to Python
Introduction to Python
 
Python入門 : 4日間コース社内トレーニング
Python入門 : 4日間コース社内トレーニングPython入門 : 4日間コース社内トレーニング
Python入門 : 4日間コース社内トレーニング
 
PyCon Taiwan 2013 Tutorial
PyCon Taiwan 2013 TutorialPyCon Taiwan 2013 Tutorial
PyCon Taiwan 2013 Tutorial
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 

Similar to Python Puzzlers - 2016 Edition

Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
Eelco Visser
 
Advanced python
Advanced pythonAdvanced python
Advanced python
EU Edge
 
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in FortranFramework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
Patrick Diehl
 
Detecting Bugs in Binaries Using Decompilation and Data Flow Analysis
Detecting Bugs in Binaries Using Decompilation and Data Flow AnalysisDetecting Bugs in Binaries Using Decompilation and Data Flow Analysis
Detecting Bugs in Binaries Using Decompilation and Data Flow Analysis
Silvio Cesare
 

Similar to Python Puzzlers - 2016 Edition (20)

Python to scala
Python to scalaPython to scala
Python to scala
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
 
The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196
 
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in FortranFramework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
Framework for Extensible, Asynchronous Task Scheduling (FEATS) in Fortran
 
The Ring programming language version 1.5.1 book - Part 174 of 180
The Ring programming language version 1.5.1 book - Part 174 of 180 The Ring programming language version 1.5.1 book - Part 174 of 180
The Ring programming language version 1.5.1 book - Part 174 of 180
 
The Ring programming language version 1.9 book - Part 98 of 210
The Ring programming language version 1.9 book - Part 98 of 210The Ring programming language version 1.9 book - Part 98 of 210
The Ring programming language version 1.9 book - Part 98 of 210
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Functions and Relations
Functions and RelationsFunctions and Relations
Functions and Relations
 
The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180The Ring programming language version 1.5.1 book - Part 30 of 180
The Ring programming language version 1.5.1 book - Part 30 of 180
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
 
Chapter 02 functions -class xii
Chapter 02   functions -class xiiChapter 02   functions -class xii
Chapter 02 functions -class xii
 
Functional object
Functional objectFunctional object
Functional object
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Detecting Bugs in Binaries Using Decompilation and Data Flow Analysis
Detecting Bugs in Binaries Using Decompilation and Data Flow AnalysisDetecting Bugs in Binaries Using Decompilation and Data Flow Analysis
Detecting Bugs in Binaries Using Decompilation and Data Flow Analysis
 
Operators inc c language
Operators inc c languageOperators inc c language
Operators inc c language
 

Recently uploaded

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Recently uploaded (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 

Python Puzzlers - 2016 Edition

  • 1. Python Puzzlers Feb 17, 2016 Nandan Sawant, Ryan Rueth
  • 3. Defaulter def extend_list(val, l=[]): l.append(val) return l list1 = extend_list(10) list2 = extend_list(123,[]) list3 = extend_list('a') print "list1 = %s" % list1 print "list2 = %s" % list2 print "list3 = %s" % list3
  • 4. Defaulter def extend_list(val, l=[]): l.append(val) return l list1 = extend_list(10) list2 = extend_list(123,[]) list3 = extend_list('a') print "list1 = %s" % list1 print "list2 = %s" % list2 print "list3 = %s" % list3 list1 = [10, 'a'] list2 = [123] list3 = [10, 'a']
  • 5. Defaulter From the python documentation: https://docs.python.org/2/reference/compound_stmts.html#function-definitions ● Avoid mutable default arguments ● If you use mutable default arguments, ○ don’t mutate them ○ have a good reason to mutate them (e.g. caching)
  • 6. Defaulter def extend_list(val, l=None): if l is None: l = [] l.append(val) return l list1 = extend_list(10) list2 = extend_list(123,[]) list3 = extend_list('a') print "list1 = %s" % list1 print "list2 = %s" % list2 print "list3 = %s" % list3 list1 = [10] list2 = [123] list3 = ['a']
  • 8. Who’s late? multipliers = [lambda x: (i+1)*x for i in range(10)] def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2)
  • 9. Who’s late? multipliers = [lambda x: (i+1)*x for i in range(10)] def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2) [20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
  • 10. Who’s late? multipliers = [] for i in range(10): def multiplier(x): return (i+1) * x multipliers.append(multiplier) def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2)
  • 11. Who’s late? multipliers = [] for i in range(10): def multiplier(x): return (i+1) * x multipliers.append(multiplier) def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2) [20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
  • 12. ● A closure occurs when a function has access to a local variable from an enclosing scope that has finished its execution ● Closures in python are late-binding ● This means that the values of variables used in closures are looked up at the time the closure is called ● This behavior is NOT specific to lambdas Who’s late?
  • 13. Who’s late? multipliers = [lambda x, i=i: (i+1)*x for i in range(10)] def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2) [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  • 14. Who’s late? from functools import partial from operator import mul multipliers = [partial(mul, i+1) for i in range(10)] def print_multiplication_table_for(number): print [multiplier(number) for multiplier in multipliers] print_multiplication_table_for(2) [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  • 17. Western Addition (A) a = b = [1,2,3] a += [4] print a, b a = a + [5] print a, b
  • 18. Western Addition (A) a = b = [1,2,3] a += [4] print a, b a = a + [5] print a, b [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 5] [1, 2, 3, 4]
  • 19. ● a + b uses __add__ while a += b uses __iadd__ ● An object's __add__ method is regular addition: it takes two parameters, returns their sum, and doesn't modify either parameter ● An object's __iadd__ method also takes two parameters, but makes the change in-place, modifying the contents of the first parameter Western Addition (A)
  • 21. Western Addition (B) a = b = 'western' a += 'addition' print a, b a = a + 'sf' print a, b
  • 22. Western Addition (B) a = b = 'western' a += 'addition' print a, b a = a + 'sf' print a, b westernaddition western westernadditionsf western
  • 23. ● a + b uses __add__ while a += b uses __iadd__, if it exists ● An object's __add__ method is regular addition: it takes two parameters, returns their sum, and doesn't modify either parameter ● An object's __iadd__ method also takes two parameters, but makes the change in-place, modifying the contents of the first parameter ● Because this requires object mutation, immutable types (like Strings!) don’t have an __iadd__ method Western Addition (B)
  • 25. Western Addition (C) a = ([1,2,3],) a[0] += [4] print a
  • 26. Western Addition (C) a = ([1,2,3],) a[0] += [4] print a TypeError: 'tuple' object does not support item assignment ([1, 2, 3, 4],)
  • 27. ● An object's __iadd__ method takes two parameters, but makes the change in-place, modifying the contents of the first parameter and returns the first parameter ● The code above is equivalent to: Western Addition (C) a = ([1,2,3],) x = a[0] x = x.__iadd__([4]) # returns x itself a[0] = x
  • 29. Western Addition (D) a = b = 500 print a is b a -= 200 b -= 200 print a is b a = a - 200 b = b - 200 print a is b --a --b print a is b
  • 30. Western Addition (D) a = b = 500 print a is b a -= 200 b -= 200 print a is b a = a - 200 b = b - 200 print a is b --a --b print a is b True False True True
  • 31. From the python documentation: https://docs.python.org/2/c-api/int.html Western Addition (D) ● There is no decrement (--) operator in python ● -- is simply two negation operators
  • 32. 4. Crossing the Boundary
  • 34. Crossing the Boundary (A) a, b = 0, 1 def fib(n): for i in range(n): a, b = b, a + b return a print fib(4)
  • 35. Crossing the Boundary (A) a, b = 0, 1 def fib(n): for i in range(n): a, b = b, a + b return a print fib(4) UnboundLocalError: local variable 'b' referenced before assignment
  • 36. Crossing the Boundary (A) x = 1 def f1(): print x f1() print x x = 1 def f2(): x = 2 print x f2() print x x = 1 def f3(): print x x = 3 f3() print x
  • 37. Crossing the Boundary (A) x = 1 def f1(): print x f1() print x x = 1 def f2(): x = 2 print x f2() print x x = 1 def f3(): print x x = 3 f3() print x 1 1 2 1 UnboundLocalError: local variable 'x' referenced before assignment 1
  • 38. ● If we want to access a global variable from inside a function, it is possible ● The assignment statement inside a function creates variables in the local scope ● If a local variable has the same name as a global variable the local variable will always take precedence ● The assignment inside the function does not modify the global variable ● We may not refer to both a global variable and a local variable by the same name inside the same function, it gives us an error ● Deep Dive http://eli.thegreenplace.net/2011/05/15/understanding-unboundlocalerror-in-python Crossing the Boundary (A)
  • 39. Crossing the Boundary (A) a, b = 0, 1 def fib(n): for i in range(n): global a, b a, b = b, a + b return a print fib(4) 3
  • 44. Crossing the Boundary (C) main.py try: import quitter except: exit(0) quitter.quit() quitter.py def quit(): exit(0) # Add one indented line here # to make main.py crash python main.py
  • 45. Crossing the Boundary (C) main.py try: import quitter except: exit(0) quitter.quit() quitter.py def quit(): exit(0) exit = None python main.py
  • 46. Crossing the Boundary (C) main.py try: import quitter except: exit(0) quitter.quit() quitter.py def quit(): exit(0) exit = None UnboundLocalError: local variable 'exit' referenced before assignment python main.py
  • 49. Kids These Days (A) class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print Parent.x, Child1.x, Child2.x Child1.x = 2 print Parent.x, Child1.x, Child2.x Parent.x = 3 print Parent.x, Child1.x, Child2.x
  • 50. Kids These Days (A) class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print Parent.x, Child1.x, Child2.x Child1.x = 2 print Parent.x, Child1.x, Child2.x Parent.x = 3 print Parent.x, Child1.x, Child2.x 1 1 1 1 2 1 3 2 3
  • 51. ● In Python, class variables are internally handled as dictionaries. ● If a variable name is not found in the dictionary of the current class, the class hierarchy (i.e., its parent classes) are searched until the referenced variable name is found ● If the referenced variable name is not found in the class itself or anywhere in its hierarchy, an AttributeError occurs Kids These Days (A)
  • 53. Kids These Days (B) class Parent: x = 1 class Child1(Parent): pass class Child2(Parent): x = 2 class GrandChild(Child1, Child2): pass print GrandChild.x
  • 54. Kids These Days (B) class Parent: x = 1 class Child1(Parent): pass class Child2(Parent): x = 2 class GrandChild(Child1, Child2): pass print GrandChild.x 1
  • 55. Kids These Days (B) class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): x = 2 class GrandChild(Child1, Child2): pass print GrandChild.x 2
  • 56. ● If you don’t inherit from ‘object’, you’re defining an old style class ● MRO is Method Resolution Order. Lookup __mro__ ● MRO for old style classes follows a native DFS approach Grandchild -> Child 1 -> Parent -> Child 2 -> Parent ● MRO for new style classes is more sensible Grandchild -> Child 1 -> Child 2 -> Parent ● Don’t use old-style classes Kids These Days (B)
  • 58. Exceptional Circumstances user_id = 'a' try: user_id = int(user_id) print user_id except TypeError, ValueError: print "Oops!" (a) a (b) 65 (c) Oops! (d) raises TypeError (e) raises ValueError
  • 59. Exceptional Circumstances user_id = 'a' try: user_id = int(user_id) print user_id except TypeError, ValueError: print "Oops!" (a) a (b) 65 (c) Oops! (d) raises TypeError (e) raises ValueError ValueError: invalid literal for int() with base 10: 'a'
  • 60. Exceptional Circumstances user_id = 'a' try: user_id = int(user_id) print user_id except (TypeError, ValueError): print "Oops!" (a) a (b) 65 (c) Oops! (d) raises TypeError (e) raises ValueError
  • 61. ● If you’re catching multiple exceptions in python 2.x, you must enclose them in parentheses ● If you do not, the second argument to except is treated as a reference to the exception object. E.g. this may look familiar: except Exception, e ● This problem goes away in python 3.x as except Exception, e is not a valid syntax. It is replaced by except Exception as e Exceptional Circumstances
  • 63. So long! x = set([type(1), type(1L), type(1.0)]) y = set([1.__class__, 1L.__class__, 1.0.__class__]) print x == y (a) True (b) False (c) TypeError (d) None of the above
  • 64. So long! x = set([type(1), type(1L), type(1.0)]) y = set([1.__class__, 1L.__class__, 1.0.__class__]) print x == y (a) True (b) False (c) TypeError (d) None of the above y = set([1.__class__, 1L.__class__, 1.0.__class__]) ^ SyntaxError: invalid syntax
  • 65. It is a tokenization issue! The . is parsed as the beginning of the fractional part of a floating point number. When it encounters something other than a number, it will throw an error. So long!
  • 66. So long! x = set([type(1), type(1L), type(1.0)]) y = set([(1).__class__, 1L.__class__, 1.0.__class__]) print x == y (a) True (b) False (c) TypeError (d) None of the above
  • 68. Zilch z = False i = [] l = 0, c = None h = {} print any((z, i, l, c, h)) (a) True (b) False (c) (False, False, False, False, False) (d) None of the above
  • 69. Zilch z = False i = [] l = 0, c = None h = {} print any((z, i, l, c, h)) (a) True (b) False (c) (False, False, False, False, False) (d) None of the above
  • 70. Zilch z = False i = [] l = 0, c = None h = {} print any((z, i, l, c, h)) (a) True (b) False (c) (False, False, False, False, False) (d) None of the above
  • 71. When creating a tuple, in all cases except the empty tuple, the comma is the important thing. Parentheses are only required for other syntactic reasons: to distinguish a tuple from a set of function arguments, operator precedence, or to allow line breaks. Zilch https://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences
  • 73. It’s 2016! print 2,016 * 2,016 (a) 4064256 (b) 4,064,256 (c) 4 256 (d) 2 32 16 (e) None of the above
  • 74. It’s 2016! print 2,016 * 2,016 (a) 4064256 (b) 4,064,256 (c) 4 256 (d) 2 32 16 (e) None of the above 2 28 14
  • 75. The 0 is an outdated prefix that Python 2.x uses to represent Octal numbers. In Python 3, you must write: 0o16 instead. It’s 2016!
  • 77. Finally def find_inverse(n): inverse = 1 try: inverse = 1 / k finally: return inverse fi = find_inverse print fi(-1) + fi(0) + fi(1) (a) 0 (b) 1 (c) 3 (d) raises ZeroDivisionError (e) raises NameError (f) None of the above
  • 78. Finally def find_inverse(n): inverse = 1 try: inverse = 1 / k finally: return inverse fi = find_inverse print fi(-1) + fi(0) + fi(1) (a) 0 (b) 1 (c) 3 (d) raises ZeroDivisionError (e) raises NameError (f) None of the above
  • 80. return in finally will swallow the actual return value in the try block return in finally will swallow the exception Finally
  • 81. References ● How to format code within a presentation ● Python Puzzlers by Tendayi Mawushe at PyCon Ireland 2010 ● Python Puzzlers by Alan Pierce at Khan Academy ● Python Epiphanies by Stuart Williams at PyCon Montreal 2015 ● Python Interview Questions ● Python Gotchas ● Raymon Hettinger’s twitter feed @raymondh