-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit of PyCon 2018 talk slides and material.
- Loading branch information
0 parents
commit 50640d7
Showing
50 changed files
with
718 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file not shown.
Oops, something went wrong.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())) |