Skip to content

Commit

Permalink
Initial commit of PyCon 2018 talk slides and material.
Browse files Browse the repository at this point in the history
  • Loading branch information
jiffyclub committed May 12, 2018
0 parents commit 50640d7
Show file tree
Hide file tree
Showing 50 changed files with 718 additions and 0 deletions.
105 changes: 105 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

# Created by https://www.gitignore.io/api/python

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Translations
*.mo
*.pot

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule.*

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/


# End of https://www.gitignore.io/api/python
310 changes: 310 additions & 0 deletions Firewall Demo Animation.ipynb

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Python Performance Investigation by Example

Slides [here](./presentation/Python Performance Investigation - PyCon 2018.pdf).

Use `snakeviz slow_mode.cprof` to see the SnakeViz profile demo'd in the talk.
(Requires Python 3.)
114 changes: 114 additions & 0 deletions Scanner Position Plot.ipynb

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions day13/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
0: 3
1: 2
2: 4
4: 6
6: 4
8: 6
10: 5
12: 6
14: 9
16: 6
18: 8
20: 8
22: 8
24: 8
26: 8
28: 8
30: 12
32: 14
34: 10
36: 12
38: 12
40: 10
42: 12
44: 12
46: 12
48: 12
50: 12
52: 14
54: 14
56: 12
62: 12
64: 14
66: 14
68: 14
70: 17
72: 14
74: 14
76: 14
82: 14
86: 18
88: 14
96: 14
98: 44
Binary file added fast_mode.cprof
Binary file not shown.
46 changes: 46 additions & 0 deletions fast_mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import itertools


def puzzle_input() -> dict:
with open('./day13/input.txt') as f:
return {
layer: range_
for layer, range_ in (
map(int, row.strip().split(': ')) for row in f)}


def scanner_layer(scanner_height: int, time_step: int) -> int:
"""
Calculates the position of a scanner within its range at a
given time step.
"""
cycle_midpoint = scanner_height - 1
full_cycle = cycle_midpoint * 2
cycle_position = time_step % full_cycle
return (
cycle_position
if cycle_position <= cycle_midpoint
else full_cycle - cycle_position)


def check_capture(firewall: dict, num_layers: int, t_start: int) -> bool:
"""Returns True if the packet is caught while crossing, otherwise False."""
for pos in range(num_layers):
if pos in firewall:
scanner_height = firewall[pos]
scanner_pos = scanner_layer(scanner_height, t_start + pos)
if scanner_pos == 0:
return True
return False


def find_start(firewall: dict) -> int:
num_layers = max(firewall.keys()) + 1
for t_start in itertools.count(0):
if not check_capture(firewall, num_layers, t_start):
break
return t_start


print(find_start(puzzle_input()))
Binary file added images/frame00.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame00_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame01.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame01_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame02.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame02_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame03.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame03_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame04.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame04_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame05.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame05_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame06.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame06_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame07.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame07_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame08.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame08_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame09.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame09_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame10.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame10_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame11.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame11_.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame12.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/frame12_.gif
Binary file added images/frame13.gif
Binary file added images/frame13_.gif
Binary file added images/frame14.gif
Binary file added images/frame14_.gif
Binary file added images/frame15.gif
Binary file added images/frame15_.gif
Binary file added images/frame16.gif
Binary file added images/frame16_.gif
Binary file added images/frame17.gif
Binary file added images/frame17_.gif
Binary file added images/scanner_position.pdf
Binary file not shown.
Binary file added images/scanners.gif
Binary file added images/snakeviz_screenshot.png
Binary file not shown.
Binary file not shown.
Binary file added slow_mode.cprof
Binary file not shown.
94 changes: 94 additions & 0 deletions slow_mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import itertools
from typing import Dict, Iterator


class Scanner:
"""Holds the state of a single scanner."""
def __init__(self, layer: int, range_: int):
self.layer = layer
self.range_ = range_
self.pos = 0
self.dir_ = 'down'

def advance(self):
"""Advance this scanner one time step."""
if self.dir_ == 'down':
self.pos += 1
if self.pos == self.range_ - 1:
self.dir_ = 'up'
else:
self.pos -= 1
if self.pos == 0:
self.dir_ = 'down'

def copy(self):
"""Make a copy of this scanner in the same state."""
inst = self.__class__(self.layer, self.range_)
inst.pos = self.pos
inst.dir_ = self.dir_
return inst


def init_firewall(rows: Iterator[str]) -> Dict[int, Scanner]:
"""Create a dictionary of scanners from the puzzle input."""
firewall = {}
for row in rows:
layer, range_ = (int(x) for x in row.split(': '))
firewall[layer] = Scanner(layer, range_)
return firewall


def puzzle_input() -> Dict[int, Scanner]:
"""Helper for loading puzzle input."""
with open('./day13/input.txt') as f:
return init_firewall(f)


def check_capture(
firewall: Dict[int, Scanner], num_layers: int) -> bool:
"""Returns True if the packet is caught while crossing, otherwise False."""
for packet_pos in range(num_layers):
# check if the scanner is captured in this position
if packet_pos in firewall and firewall[packet_pos].pos == 0:
return True

# advance scanners to their next positions
for scanner in firewall.values():
scanner.advance()

return False


def copy_firewall(
firewall: Dict[int, Scanner]) -> Dict[int, Scanner]:
"""Make a copy of a firewall dictionary"""
return {
layer: scanner.copy() for layer, scanner in firewall.items()
}


def find_start(firewall: Dict[int, Scanner]) -> int:
"""Attempt crossing until we make it uncaught."""
loop_firewall = copy_firewall(firewall)
num_layers = max(firewall.keys()) + 1

for t_start in itertools.count(0):
# save the state of the firewall before we start to cross
# so we can use it as the basis of a potential next attempt
pre_check_firewall = copy_firewall(loop_firewall)

# check if the packet is caught while attempting a crossing starting
# at this time step
if check_capture(loop_firewall, num_layers):
# reset to pre-check state and advance once
# so we can attempt a crossing at the next timestep
loop_firewall = copy_firewall(pre_check_firewall)
for scanner in loop_firewall.values():
scanner.advance()
else:
break

return t_start


print(find_start(puzzle_input()))

0 comments on commit 50640d7

Please sign in to comment.