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