Compare commits
25 Commits
matplotlib
...
master
Author | SHA1 | Date |
---|---|---|
|
3b33dc23c0 | 2 years ago |
|
62cfa5de1f | 2 years ago |
|
7c56c9fa6f | 2 years ago |
|
6caaf3e31f | 2 years ago |
|
096a2beb07 | 2 years ago |
|
17e5ffba53 | 2 years ago |
|
d2e8aa0b78 | 2 years ago |
|
cb6b78aeec | 2 years ago |
|
b699b2146c | 2 years ago |
|
affb0a3a27 | 2 years ago |
|
728f67de93 | 2 years ago |
|
50c09332e1 | 2 years ago |
|
a750e8a47f | 2 years ago |
|
b167092366 | 2 years ago |
|
f110972d79 | 2 years ago |
|
a1e4e78f03 | 2 years ago |
|
509f8123a2 | 2 years ago |
|
3e79c402cc | 2 years ago |
|
d02427df20 | 2 years ago |
|
04df494617 | 2 years ago |
|
b86934cf49 | 2 years ago |
|
6c34b9940f | 2 years ago |
|
bc01ea89d5 | 2 years ago |
|
c5bc7c4c81 | 2 years ago |
|
1f6da02144 | 2 years ago |
@ -0,0 +1,29 @@
|
|||||||
|
pipeline:
|
||||||
|
standardize:
|
||||||
|
image: python:${TAG}-buster
|
||||||
|
commands:
|
||||||
|
- python -m pip install --upgrade pip
|
||||||
|
# - python -m pip install -r requirements.txt
|
||||||
|
- python -m pip install pylint flake8 mypy>=0.971
|
||||||
|
- python -m flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
|
# - mypy --strict serial_sphinx/
|
||||||
|
# - python -m pylint -f parseable serial_sphinx/*.py
|
||||||
|
|
||||||
|
build:
|
||||||
|
image: python:${TAG}-buster
|
||||||
|
commands:
|
||||||
|
- ls
|
||||||
|
- python -m venv venv
|
||||||
|
- /bin/bash -c "source venv/bin/activate"
|
||||||
|
- python -m pip install --upgrade pip pytest
|
||||||
|
# - python -m pip install -r requirements.txt
|
||||||
|
- python -m pip install .
|
||||||
|
- python -m pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
TAG:
|
||||||
|
- 3.9
|
||||||
|
- 3.10
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2022 Tom Weber
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@ -1,79 +0,0 @@
|
|||||||
import matplotlib.animation as animation
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
#import plotly.graph_objects as go
|
|
||||||
import plotly.express as px
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
class PlotlyAnimation(object):
|
|
||||||
def __init__(self, state, steps):
|
|
||||||
self.state = state
|
|
||||||
self.steps = steps
|
|
||||||
self.frames = np.expand_dims(self.state.board, axis=0)
|
|
||||||
self.frame_gen()
|
|
||||||
self.animation = self.animation_gen()
|
|
||||||
|
|
||||||
def frame_gen(self):
|
|
||||||
for _ in range(self.steps):
|
|
||||||
self.frames = np.concatenate((self.frames, np.expand_dims(self.state.step(), axis=0)), axis=0)
|
|
||||||
return self.frames
|
|
||||||
|
|
||||||
def animation_gen(self):
|
|
||||||
fig = px.imshow(self.frames, animation_frame=0)
|
|
||||||
fig.layout.updatemenus[0].buttons[0].args[1]['frame']['duration'] = 30
|
|
||||||
fig.layout.updatemenus[0].buttons[0].args[1]['transition']['duration'] = 5
|
|
||||||
fig.layout.updatemenus[0].showactive = True
|
|
||||||
fig.layout.sliders[0].visible = False
|
|
||||||
fig.layout.coloraxis.showscale = False
|
|
||||||
fig.layout.xaxis.showticklabels = False
|
|
||||||
fig.layout.yaxis.showticklabels = False
|
|
||||||
return fig
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
self.animation.show()
|
|
||||||
|
|
||||||
|
|
||||||
class PltAnimation(object):
|
|
||||||
def __init__(self, state, steps=None):
|
|
||||||
|
|
||||||
self.state = state
|
|
||||||
self.steps = steps
|
|
||||||
self.fig, self.ax = plt.subplots()
|
|
||||||
self.ax = self.ax.matshow(self.state.board)
|
|
||||||
|
|
||||||
def frame_yield(self):
|
|
||||||
while True:
|
|
||||||
self.state.step()
|
|
||||||
yield self.state.board
|
|
||||||
|
|
||||||
def frame_gen(self):
|
|
||||||
frames = []
|
|
||||||
for i in range(self.steps):
|
|
||||||
self.state.step()
|
|
||||||
[].append(self.state.board)
|
|
||||||
return self.ax, frames
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
return self.state.board
|
|
||||||
|
|
||||||
def update(self, data):
|
|
||||||
self.ax.set_data(data)
|
|
||||||
return self.ax
|
|
||||||
|
|
||||||
def animate(self):
|
|
||||||
if self.steps is None:
|
|
||||||
return animation.FuncAnimation(
|
|
||||||
self.fig,
|
|
||||||
self.update,
|
|
||||||
self.frame_yield,
|
|
||||||
init_func=self.init,
|
|
||||||
interval=100,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return animation.FuncAnimation(
|
|
||||||
self.fig,
|
|
||||||
self.update,
|
|
||||||
self.frame_gen,
|
|
||||||
init_func=self.init,
|
|
||||||
interval=100,
|
|
||||||
)
|
|
@ -0,0 +1,31 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "conway"
|
||||||
|
version = "0.0.1"
|
||||||
|
authors = [
|
||||||
|
{ name="Tom Weber", email="tom@weber.codes" },
|
||||||
|
]
|
||||||
|
description = "A game of life implementation"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.7"
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"numpy>=1.23.3",
|
||||||
|
"plotly>=5.11.0",
|
||||||
|
"pandas>=1.5.1"
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
"repository" = "https://git.weber.codes/tom/gameoflife"
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
addopts = [
|
||||||
|
"--import-mode=importlib",
|
||||||
|
]
|
@ -1,15 +0,0 @@
|
|||||||
contourpy==1.0.5
|
|
||||||
cycler==0.11.0
|
|
||||||
fonttools==4.37.4
|
|
||||||
kiwisolver==1.4.4
|
|
||||||
matplotlib==3.6.0
|
|
||||||
numpy==1.23.3
|
|
||||||
packaging==21.3
|
|
||||||
pandas==1.5.1
|
|
||||||
Pillow==9.2.0
|
|
||||||
plotly==5.11.0
|
|
||||||
pyparsing==3.0.9
|
|
||||||
python-dateutil==2.8.2
|
|
||||||
pytz==2022.6
|
|
||||||
six==1.16.0
|
|
||||||
tenacity==8.1.0
|
|
@ -1,19 +0,0 @@
|
|||||||
from setuptools import setup
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name='conway',
|
|
||||||
version='0.1.0',
|
|
||||||
description="A conway's game of life implementation",
|
|
||||||
url='https://git.weber.codes/tom/conwaysgameoflife',
|
|
||||||
author='Tom Weber',
|
|
||||||
author_email='mail@weber.codes',
|
|
||||||
license='BSD 2-clause',
|
|
||||||
packages=['conway'],
|
|
||||||
install_requires=['wheel',
|
|
||||||
'numpy',
|
|
||||||
'pandas',
|
|
||||||
'matplotlib',
|
|
||||||
'plotly'
|
|
||||||
],
|
|
||||||
|
|
||||||
)
|
|
@ -0,0 +1,29 @@
|
|||||||
|
import plotly.express as px
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class PlotlyAnimation(object):
|
||||||
|
def __init__(self, state, steps):
|
||||||
|
self.state = state
|
||||||
|
self.steps = steps
|
||||||
|
self.frames = np.expand_dims(self.state.board, axis=0)
|
||||||
|
self.frame_gen()
|
||||||
|
self.animation = self.animation_gen()
|
||||||
|
|
||||||
|
def frame_gen(self):
|
||||||
|
for _ in range(self.steps):
|
||||||
|
self.frames = np.concatenate((self.frames, np.expand_dims(self.state.step(), axis=0)), axis=0)
|
||||||
|
return self.frames
|
||||||
|
|
||||||
|
def animation_gen(self):
|
||||||
|
fig = px.imshow(self.frames, animation_frame=0, color_continuous_scale=[[0, "white"], [1, "black"]])
|
||||||
|
fig.layout.updatemenus[0].buttons[0].args[1]['frame']['duration'] = 30
|
||||||
|
fig.layout.updatemenus[0].buttons[0].args[1]['transition']['duration'] = 5
|
||||||
|
fig.layout.updatemenus[0].showactive = True
|
||||||
|
fig.layout.sliders[0].visible = False
|
||||||
|
fig.layout.coloraxis.showscale = False
|
||||||
|
fig.layout.xaxis.showticklabels = False
|
||||||
|
fig.layout.yaxis.showticklabels = False
|
||||||
|
return fig
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
self.animation.show()
|
@ -0,0 +1,12 @@
|
|||||||
|
import pytest
|
||||||
|
import conway.anime as anime
|
||||||
|
import conway.gameoflife as gol
|
||||||
|
|
||||||
|
|
||||||
|
class TestPlotlyAnimation:
|
||||||
|
state = gol.State(10, 10, "random")
|
||||||
|
steps = 10
|
||||||
|
plotly_anime = anime.PlotlyAnimation(state, steps)
|
||||||
|
def test_frame_gen(self):
|
||||||
|
assert self.plotly_anime.frames.shape == (11,10,10)
|
||||||
|
assert len(self.plotly_anime.frame_gen()) == 2 * self.steps + 1
|
@ -0,0 +1,17 @@
|
|||||||
|
import pytest
|
||||||
|
import numpy as np
|
||||||
|
import conway.gameoflife as gol
|
||||||
|
|
||||||
|
|
||||||
|
class TestState:
|
||||||
|
def test_neighbours(self):
|
||||||
|
state = gol.State(10, 10)
|
||||||
|
n1 = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
|
||||||
|
assert state.checkNeighbours(n1, 1, 1) == 8
|
||||||
|
assert state.checkNeighbours(n1, 1, 1, neighbourhood="neumann") == 4
|
||||||
|
n2 = np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
|
||||||
|
assert state.checkNeighbours(n2, 1, 1) == 0
|
||||||
|
assert state.checkNeighbours(n2, 1, 1, neighbourhood="neumann") == 0
|
||||||
|
n3 = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]])
|
||||||
|
assert state.checkNeighbours(n3, 1, 1, neighbourhood="moore") == 4
|
||||||
|
assert state.checkNeighbours(n3, 1, 1, neighbourhood="neumann") == 0
|
Loading…
Reference in new issue