CoffeeBreakPython September11 2018
CoffeeBreakPython September11 2018
Christian Mayer
September 2018
i
Contents
Contents ii
1 Introduction 1
2 A Case for Puzzle-based Learning 4
2.1 Overcome the Knowledge Gap . . . . . . . 5
2.2 Embrace the Eureka Moment . . . . . . . 7
2.3 Divide and Conquer . . . . . . . . . . . . 8
2.4 Improve From Immediate Feedback . . . . 9
2.5 Measure Your Skills . . . . . . . . . . . . . 10
2.6 Individualized Learning . . . . . . . . . . . 13
2.7 Small is Beautiful . . . . . . . . . . . . . . 14
2.8 Active Beats Passive Learning . . . . . . . 16
2.9 Make Code a First-class Citizen . . . . . . 18
2.10 What You See is All There is . . . . . . . 20
ii
CONTENTS iii
Introduction
1
2 CHAPTER 1. INTRODUCTION
The idea is that you solve code puzzles that start out
simple but become more and more complex as you read
the book. In essence, you play Python interpreter and
compute the output of a code snippet in your head. Then
you check whether you were right with your guessusing
feedback and explanationsto adapt and improve your
coding skills over time. To make this idea a reality, I
developed the online coding academy Finxter.com. The
next section explains and motivates the advantages of the
Finxter method of puzzle-based learning.
2
4
2.1. OVERCOME THE KNOWLEDGE GAP 5
2 https://en.wikipedia.org/wiki/Active_learning#
Research_evidence
3 http://journals.sagepub.com/doi/abs/10.1177/
1529100612453266
2.8. ACTIVE BEATS PASSIVE LEARNING 17
Pick any sport you always loved to do. How good are
you compared to others? The Elo rating answers this
question with surprising accuracy. It assigns a number
to each player that represents their skill in the sport. The
higher the Elo number, the better the player.
22
3.1. HOW TO USE THIS BOOK 23
Table 3.1 shows the ranks for each Elo rating level.
The table is an opportunity for you to estimate your
Python skill level. In the following, I describe how you
can use this book to test your Python skills.
This was the gold standard for all the puzzles created
in this book. I did my best to adhere to this standard.
26 CHAPTER 3. THE ELO RATING FOR PYTHON
Grand master
2500
2000
1500
Your Elo
1000
500
Beginner, 50% correct Beginner, 0% correct
0 Intermediate, 50% correct Advanced, 100% correct
Advanced, 50% correct
0 10 20 30 40 50
Number of Solved Puzzles
4. Make sure you carry a pen with you and write your
solution into the book. This ensures that you stay
objectivewe all have the tendency to fake our-
selves. Active learning is a central idea of this book.
planation.
Language
36
4.1. KEYWORDS 37
PDFs and post them to your wall until you know them
by heart:
https://blog.finxter.com/python-cheat-sheet/.
4.1 Keywords
All programming languages reserve certain words to have
a special meaning. These words are called keywords.
With keywords, the programmer can issue commands to
the compiler or interpreter. They let you tell the com-
puter what to do. Without keywords, the computer could
not make sense from the seemingly random text in your
code le. Note that as keywords are reserved words, you
cannot use them as variable names.
4.4 Classes
Object-oriented programming is an inuential, powerful,
and expressive programming abstraction. The program-
mer thinks in terms of classes and objects. A class is a
blueprint for an object. An object contains specic data
and provides the functionality specied in the class.
ADVANCED FUNCTIONS
map(func, iter)
Executes the function on all elements of the iterable. Example:
list(map(lambda x: x[0], ['red', 'green', 'blue']))
# Result: ['r', 'g', 'b']
map(func, i1, ..., ik)
Executes the function on all k elements of the k iterables. Example:
list(map(lambda x, y: str(x) + ' ' + y + 's' , [0, 2, 2],
['apple', 'orange', 'banana']))
# Result: ['0 apples', '2 oranges', '2 bananas']
string.join(iter)
Concatenates iterable elements separated by string. Example:
' marries '.join(list(['Alice', 'Bob']))
# Result: 'Alice marries Bob'
filter(func, iterable)
Filters out elements in iterable for which function returns False (or 0). Example:
list(filter(lambda x: True if x>17 else False, [1, 15, 17,
18])) # Result: [18]
string.strip()
Removes leading and trailing whitespaces of string. Example:
print(" \n \t 42 \t ".strip()) # Result: 42
sorted(iter)
Sorts iterable in ascending order. Example:
sorted([8, 3, 2, 42, 5]) # Result: [2, 3, 5, 8, 42]
sorted(iter, key=key)
Sorts according to the key function in ascending order. Example:
sorted([8, 3, 2, 42, 5], key=lambda x: 0 if x==42 else x)
# [42, 2, 3, 5, 8]
help(func)
Returns documentation of func. Example:
CHAPTER 4. A QUICK OVERVIEW OF THE
52 PYTHON LANGUAGE
Unpacking arguments
Use a sequence as function arguments via asterisk operator *. Use a dictionary
(key, value) via double asterisk operator **. Example:
def f(x, y, z):
return x + y * z
f(*[1, 3, 4]) # 13
f(**{'z' : 4, 'x' : 1, 'y' : 3}) # 13
Extended Unpacking
Use unpacking for multiple assignment feature in Python. Example:
a, *b = [1, 2, 3, 4, 5]
# Result: a = 1, b = [2, 3, 4, 5]
Merge two dictionaries
Use unpacking to merge two dictionaries into a single one. Example:
x={'Alice' : 18}
y={'Bob' : 27, 'Ann' : 22}
z = {**x,**y}
# Result: z = {'Alice': 18, 'Bob': 27, 'Ann': 22}
5
54
5.1. HELLO WORLD 55
print('hello world')
x = 55 / 11
print(x)
Puzzle 3
#############################
## id 314
## Puzzle Elo 666
## Correctly solved 75 %
#############################
x = 50 * 2 + (60 - 20) / 4
print(x)
# This is a comment
answer = 42 # the answer
# Is this a comment?
5.4. COMMENTS AND STRINGS 63
Puzzle 5
#############################
## id 331
## Puzzle Elo 742
## Correctly solved 63 %
#############################
x = 'silent'
print(x[2] + x[1] + x[0]
+ x[5] + x[3] + x[4])
String s: s i l e n t
Index: 0 1 2 3 4 5
Puzzle 6
#############################
## id 337
## Puzzle Elo 745
## Correctly solved 91 %
#############################
1 https://en.wikipedia.org/wiki/List_(abstract_data_
type)
68 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 7
#############################
## id 336
## Puzzle Elo 778
## Correctly solved 72 %
#############################
word = "galaxy"
print(len(word[1:]))
5
5.7. SLICING IN STRINGS 71
x = 50 // 11
print(x)
Puzzle 9
#############################
## id 327
## Puzzle Elo 786
## Correctly solved 60 %
#############################
x = 'py' 'thon'
print(x)
print(sum(range(0, 7)))
Puzzle 12
#############################
## id 341
## Puzzle Elo 821
## Correctly solved 71 %
#############################
This puzzle shows how you can add a new value to the
end of the list using the append() function. Before ap-
pending, the Python interpreter evaluates the expression
given within the brackets. Recall that the ** operator
returns the power function, i.e., 4 ** 3 reads four to the
power of three.
Puzzle 13
#############################
## id 335
## Puzzle Elo 829
## Correctly solved 83 %
#############################
word = "galaxy"
print(word[4:50])
x = 51 % 3
print(x)
print(if_confusion(3, 7))
Here are a few tips for the latter group. Never let
the sheer mass of code intimidate you. You do not have
to read each and every line to adhere to any kind of
perfectionism. Your computer does not execute the code
strictly from top to bottom and you shouldn't as well.
Instead, start where the programm execution starts: at
the bottom with the function call if_confusion(3, 7).
Now you know that x=3 and y=7. Then you proceed to
do what the interpreter does. As x>y is false, you can
skip the whole upper part of the function. Similarly, you
can skip the if branch for x-2>y-4. It's easy to see that
the function returns 'H'.
H
5.15. BRANCHING STATEMENTS 89
Puzzle 16
#############################
## id 332
## Puzzle Elo 848
## Correctly solved 54 %
#############################
x = 'cool'
print(x[-1] + x[-2]
+ x[-4] + x[-3])
3
5
94 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 18
#############################
## id 358
## Puzzle Elo 899
## Correctly solved 61 %
#############################
def func(x):
return x + 1
f = func
print(f(2) + func(2))
6
5.18. FUNCTIONS AND NAMING 97
Puzzle 19
#############################
## id 334
## Puzzle Elo 954
## Correctly solved 45 %
#############################
word = "galaxy"
print(word[:-2] + word[-2:])
Use the bracket notation for slicing with the start and
end position identiers. For example, word[i:j] returns
the substring starting from index i (included) and ending
5.19. CONCATENATING SLICES 99
in index j (excluded).
Puzzle 20
#############################
## id 365
## Puzzle Elo 1005
## Correctly solved 57 %
#############################
A
B
C
def ping(i):
if i > 0:
return pong(i - 1)
return "0"
def pong(i):
if i > 0:
return ping(i - 1)
return "1"
print(ping(29))
1
104 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 22
#############################
## id 333
## Puzzle Elo 1038
## Correctly solved 53 %
#############################
word = "bender"
print(word[1:4])
b e n d e r
0 1 2 3 4 5
Puzzle 24
#############################
## id 360
## Puzzle Elo 1152
## Correctly solved 50 %
#############################
a = ['a', 'b']
n = [1, 2]
x = [a, n]
print(x[1])
Puzzle 27
#############################
## id 343
## Puzzle Elo 1248
## Correctly solved 47 %
#############################
# Fibonacci series:
a, b = 0, 1
while b < 5:
print(b)
a, b = b, a + b
1 1 2 3
120 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 29
#############################
## id 355
## Puzzle Elo 1311
## Correctly solved 54 %
#############################
3
5
7
Puzzle 30
#############################
## id 351
## Puzzle Elo 1346
## Correctly solved 52 %
#############################
print(range(5, 10)[-1])
print(range(0, 10, 3)[2])
print(range(-10, -100, -30)[1])
The rst line prints the last element of the range se-
quence. A short reminder: the upper bound range pa-
124 CHAPTER 5. FIFTY CODE PUZZLES
-40
5.30. INDEXING REVISITED AND THE RANGE
SEQUENCE 125
j = len(matrix) - 1
for row in matrix:
while row[j] > value:
j = j - 1
if j == -1:
return False
if row[j] == value:
return True
return False
The algorithm starts with the rst row and the last
column j = len(matrix) - 1. Then, it skips one col-
umn at-a-time by decreasing the parameter j monoton-
ically (j = j - 1). Why can it skip the whole column?
Because as long as the column value row[j] is larger
than the searched value value, all following elements of
column j are larger than the searched value (sorted prop-
erty). Thus, we are sure that our searched value is not
in column j and we can skip this column completely by
decreasing j.
2 http://www.keithschwarz.com/interesting/code/
matrix-find/MatrixFind.python.html
130 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 32
#############################
## id 36
## Puzzle Elo 1407
## Correctly solved 65 %
#############################
def maximum_profit(prices):
'''Maximum profit of a single buying low and
,→ selling high'''
profit = 0
for i, buy_price in enumerate(prices):
sell_price = max(prices[i:])
profit = max(profit, sell_price -
,→ buy_price)
return profit
27
5.32. MAXIMUM PROFIT ALGORITHM 133
def bubble_sort(lst):
'''Implementation of bubble sort
,→ algorithm'''
Puzzle 34
#############################
## id 367
## Puzzle Elo 1437
## Correctly solved 53 %
#############################
x = 5 * 3.8 - 1
print(x)
Most nxters believe that the puzzle asks for the re-
sult of the computation here. But this is a trap! The
purpose of solving Python puzzles is to understand code
in a precise and deep manner. Deep understanding tells
you that the oat 3.80 causes the interpreter to per-
form oating point arithmetic. Thus, the result is not an
integeri.e., the value 18but a oati.e., the value
18.0.
These kinds of mistakes seem to be negligible but they
140 CHAPTER 5. FIFTY CODE PUZZLES
Puzzle 36
#############################
id 159
## Puzzle Elo 1492
## Correctly solved 33 %
#############################
l = [0, 1, 2, 3, 4, 5, 6]
x = 6
print(bsearch(l,x))
mouse
146 CHAPTER 5. FIFTY CODE PUZZLES
def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
print(f(0))
print(f(1))
42
5.38. THE LAMBDA FUNCTION 149
43
Puzzle 39
#############################
## id 325
## Puzzle Elo 1623
## Correctly solved 71 %
#############################
print("""
A
B
C
""" == "\nA\nB\nC\n")
string. We specify the line breaks with the new line char-
acter '\n'.
5.40 Escaping
Puzzle 40
#############################
## id 323
## Puzzle Elo 1629
## Correctly solved 25 %
#############################
print('P"yt\'h"on')
def fibo(n):
"""Return list containing
Fibonacci series up to n.
"""
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a + b
return result
fib100 = fibo(100)
print(fib100[-1] ==
fib100[-2] + fib100[-3])
True
5.41. FIBONACCI ARITHMETIC 157
5.42 Quicksort
Puzzle 42
#############################
## id 195
## Puzzle Elo 1672
## Correctly solved 67 %
#############################
def qsort1(L):
if L:
return qsort1([x for x in L[1:] if x <
,→ L[0]]) + L[:1] \
+ qsort1([x for x in L[1:] if x
,→ >= L[0]])
return []
def qsort2(L):
if L:
return L[:1] + qsort2([x for x in L[1:]
,→ if x < L[0]]) \
+ qsort2([x for x in L[1:] if x
,→ >= L[0]])
return []
12
5.43. UNPACKING KEYWORD ARGUMENTS
WITH DICTIONARIES 163
5.44 Innity
Puzzle 44
#############################
id 356
## Puzzle Elo 1701
## Correctly solved 40 %
#############################
print("Answer")
while True:
pass
print("42")
return False
Puzzle 46
#############################
## id 371
## Puzzle Elo 1748
## Correctly solved 44 %
#############################
lambda keyword and the colon (:) dene the function ar-
guments. The body after the colon uses the arguments
to dene the return value of the function. In the puzzle,
we use the lambda function as a key for the sorting func-
tion. The key denes that the list should be sorted by
the second value of the tuple, which is a string.
superstars = inst_names.intersection(twit_names)
print(list(superstars)[0])
words_list = ["bitcoin",
"cryptocurrency",
"wallet"]
crawled_text = '''
Research produced by the University of
Cambridge estimates that in 2017,
there are 2.9 to 5.8 million unique
users using a cryptocurrency wallet,
most of them using bitcoin.
'''
split_text = crawled_text.split()
res1 = True in map(lambda word: word in
,→ split_text, words_list)
res2 = any(word in words_list for word in
,→ split_text)
print(res1 == res2)
True
5.48. BASIC SET OPERATIONS 179
Puzzle 49
#############################
## id 391
## Puzzle Elo 1763
## Correctly solved 66 %
#############################
def encrypt(text):
encrypted = map(lambda c: chr(ord(c) + 2),
,→ text)
return ''.join(encrypted)
def decrypt(text):
decrypted = map(lambda c: chr(ord(c) - 2),
,→ text)
return ''.join(decrypted)
s = "xtherussiansarecomingx"
print(decrypt(encrypt(encrypt(s))) ==
,→ encrypt(s))
2 + 2 − 2 = 2.
Puzzle 50
#############################
## id 400
## Puzzle Elo 1780
## Correctly solved 56 %
#############################
import random
x = 100
left, right = 0, x
y = guess(left, right)
while not check(x, y):
y = guess(left, right)
print(y)
10
5.50. THE GUESS AND CHECK FRAMEWORK 185
Final Remarks
186
187