Skip to content

Commit

Permalink
use black and update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
dec1 committed Jun 20, 2024
1 parent 25385ad commit a923869
Show file tree
Hide file tree
Showing 18 changed files with 322 additions and 152 deletions.
20 changes: 11 additions & 9 deletions details.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ and I wanted to avoid requiring this of anyone else, wishing to run/test this pr

## Execute
./prj/script/venv/bin/python -m src.main
./prj/venv/bin/python -m src.main

...perc_value = 0.5967
...perc_value = 0.582025
Expand All @@ -39,7 +39,7 @@ and I wanted to avoid requiring this of anyone else, wishing to run/test this pr
![alt example](supp/img/perc_50_200x200.png)

## Test
ex_auto> ./prj/script/venv/bin/pytest test/
ex_auto> ./prj/venv/bin/pytest test/

============================= test session starts ==============================
collecting ... collected 8 items
Expand All @@ -63,13 +63,15 @@ and I wanted to avoid requiring this of anyone else, wishing to run/test this pr


## Check Typing
> ./prj/script/venv/bin/mypy --check-untyped-defs -p test -p src
> ./prj/venv/bin/mypy --check-untyped-defs -p test -p src

Success: no issues found in 18 source files

Success: no issues found in 17 source files
<!--
## Check Lint
> ./prj/script/venv/bin/python -m pylint src test
> ./prj/venv/bin/python -m pylint --errors-only src test


--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
-->
## Formatting
`> ./prj/venv/bin/black --skip-string-normalization --line-length=120 src test [--check [--diff]]`
- `--check` -dont actually modify files. list files which would be modified
- `--diff` show actual changes in files
1 change: 1 addition & 0 deletions prj/pip_reqs/pip_reqs_base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pytest
# quality control
mypy
pylint
black

numpy
matplotlib
13 changes: 6 additions & 7 deletions src/_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,27 @@

# keep mypy happy, without actually importing (and thereby creating circular dependency cluster <-> cell)
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from ._grid import Grid
from ._cluster import Cluster



class Cell:
""" Smallest individual 'unit' of a grid. Has indices (x,y) and color"""
"""Smallest individual 'unit' of a grid. Has indices (x,y) and color"""

# -------------------------------
def __init__(self, row_idx: int, col_idx: int, is_black: bool = False, grid: Optional[Grid] = None):
""" order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas """
"""order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas"""

self.col_idx: int = col_idx
self.row_idx: int = row_idx
self.col_idx: int = col_idx
self.row_idx: int = row_idx
self.is_black: bool = is_black

self.grid: Optional[Grid] = grid
self.cluster: Optional[Cluster] = None


# -------------------------------
def turn_black(self, on=True):
self.is_black = on
17 changes: 8 additions & 9 deletions src/_cell_picker.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@

import random
from typing import List, Tuple


class CellPicker:
""" Sequence of cells in (random) order from (num_rows x num_cols) sized grid"""

"""Sequence of cells in (random) order from (num_rows x num_cols) sized grid"""

# -------------------------------
def __init__(self, num_rows: int, num_cols: int):
""" order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas """
"""order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas"""
self.num_rows: int = num_rows
self.num_cols: int = num_cols

# -------------------------------
def seq_random(self, deterministic=False) -> List[Tuple[int,int]]:
""" return random sequence of cells.
if deterministic is true, then returns the same sequence every time. """
def seq_random(self, deterministic=False) -> List[Tuple[int, int]]:
"""return random sequence of cells.
if deterministic is true, then returns the same sequence every time."""

# Generate a list of all cell indices
indices = [(row, col) for row in range(self.num_rows) for col in range(self.num_cols)]

if(deterministic):
if deterministic:
random.seed(42)
# Shuffle the indices list in-place to ensure a different order each time
random.shuffle(indices)

return indices


# -------------------------------
22 changes: 10 additions & 12 deletions src/_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@

# keep mypy happy, without actually importing (and thereby creating circular dependency cluster <-> cell)
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from ._grid import Grid
from ._cell import Cell
from ._grid import Grid
from ._cell import Cell


class Cluster:
""" Full islands (not subsets thereof) of black cells """


"""Full islands (not subsets thereof) of black cells"""

# -------------------------------
def __init__(self, grid: Optional[Grid]):
Expand All @@ -24,19 +23,18 @@ def __init__(self, grid: Optional[Grid]):
self.row_idx_min: int = -1 # the closer to 0, the closer to top of grid
self.row_idx_max: int = -1 # the closer to (grid.num_cols)-1, the closer to top of grid


# -------------------------------
def num_cells(self) -> int:
return len(self.cells)

# -------------------------------
def percolates(self) -> bool:
""" does cluster extend from top to bottom of grid? """
"""does cluster extend from top to bottom of grid?"""
if self.grid is None:
return False

touches_top = self.row_idx_min == 0
touches_bottom = self.row_idx_max == (self.grid.num_rows-1)
touches_bottom = self.row_idx_max == (self.grid.num_rows - 1)

return touches_top and touches_bottom

Expand All @@ -49,19 +47,19 @@ def add_cell(self, cell: Cell):

# -------------------------------
def update_col_idx(self, cell: Cell) -> None:
""" updates col_idx_min/max if cell is closer to top/bottom of grid"""
"""updates col_idx_min/max if cell is closer to top/bottom of grid"""
if cell is None:
return

if (self.row_idx_min <0) or (self.row_idx_min > cell.row_idx) :
if (self.row_idx_min < 0) or (self.row_idx_min > cell.row_idx):
self.row_idx_min = cell.row_idx

if (self.row_idx_max <0) or (self.row_idx_max < cell.row_idx) :
if (self.row_idx_max < 0) or (self.row_idx_max < cell.row_idx):
self.row_idx_max = cell.row_idx

# -------------------------------
def merge(self, other: Cluster):
""" merges other cluster into this cluster """
"""merges other cluster into this cluster"""

if (other is None) or (other is self):
return
Expand Down
1 change: 1 addition & 0 deletions src/_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os


class Config:
# set env var "CI" to disable default plot generation

Expand Down
10 changes: 6 additions & 4 deletions src/_experiment.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@

from ._stepper import Stepper
from ._cell_picker import CellPicker
from ._grid_visual import visualize_grid_clusters, visualize_grid_sequence


class Experiment:
""" Create a grid and find percolation threshold, with visualization """
"""Create a grid and find percolation threshold, with visualization"""

def do_it(self, num_rows: int = 5, num_cols: int = 6, want_vis_seq : bool = False, want_vis_clusters : bool = False) -> int :
def do_it(
self, num_rows: int = 5, num_cols: int = 6, want_vis_seq: bool = False, want_vis_clusters: bool = False
) -> int:

stepper = Stepper(num_rows, num_cols)
seq = CellPicker(num_rows, num_cols).seq_random()
Expand All @@ -16,7 +18,7 @@ def do_it(self, num_rows: int = 5, num_cols: int = 6, want_vis_seq : bool = Fals

stepper.do_steps(seq)
grid = stepper.grid
if (grid is None):
if grid is None:
print("...empty grid in experiment??")
return -1

Expand Down
55 changes: 31 additions & 24 deletions src/_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

Row = List[Cell] # Alias for List (so we can use eg "List[Row]" instead of "List[List[Cell]]" )


class Grid:
""" Matrix of size (rows x cols) cells """
"""Matrix of size (rows x cols) cells"""

# -------------------------------
def __init__(self, num_rows: int, num_cols: int):
Expand Down Expand Up @@ -37,20 +38,23 @@ def init_cells(self):
cell = Cell(row_idx=row_idx, col_idx=col_idx, is_black=False, grid=self)
row.append(cell)
self.rows.append(row)

# -------------------------------
def perc_value(self):
return float(self.steps_taken)/(float(self.num_cols * self.num_rows))
return float(self.steps_taken) / (float(self.num_cols * self.num_rows))

# -------------------------------
@classmethod
def indices_adjacent_to(Cls, num_rows: int, num_cols: int, row_idx: int, col_idx: int) -> Optional[List[Tuple[int,int]]]:
""" return list of cells adjacent to given cell (row_idx, col_idx) in grid of size (num_rows x num_cols) """


def indices_adjacent_to(
Cls, num_rows: int, num_cols: int, row_idx: int, col_idx: int
) -> Optional[List[Tuple[int, int]]]:
"""return list of cells adjacent to given cell (row_idx, col_idx) in grid of size (num_rows x num_cols)"""

deltas = [
(-1, 0), # Above row
(0, -1), (0, 1), # Same row
(1, 0), # Below row
(-1, 0), # Above row
(0, -1),
(0, 1), # Same row
(1, 0), # Below row
]

ret = []
Expand All @@ -61,9 +65,14 @@ def indices_adjacent_to(Cls, num_rows: int, num_cols: int, row_idx: int, col_idx
ret.append((adj_row, adj_col))

return ret

# -------------------------------
def cells_adjacent_to(self, row_idx: int, col_idx: int,) -> Optional[List[Cell]]:
""" return list of cells adjacent to given cell (row_idx, col_idx) """
def cells_adjacent_to(
self,
row_idx: int,
col_idx: int,
) -> Optional[List[Cell]]:
"""return list of cells adjacent to given cell (row_idx, col_idx)"""

cell = self.cell_at(row_idx, col_idx)
if cell is None:
Expand All @@ -79,7 +88,7 @@ def cells_at(self, indices: Optional[List[Tuple[int, int]]]) -> Optional[List[Ce
if indices is None:
return ret

for (row_idx, col_idx) in indices:
for row_idx, col_idx in indices:
cell = self.cell_at(row_idx, col_idx)
if not cell is None:
ret.append(cell)
Expand All @@ -88,10 +97,10 @@ def cells_at(self, indices: Optional[List[Tuple[int, int]]]) -> Optional[List[Ce

# -------------------------------
def cell_at(self, row_idx: int, col_idx: int) -> Optional[Cell]:
""" return cell at given posn (col_idx,row_idx), or None if invalid
"""return cell at given posn (col_idx,row_idx), or None if invalid
order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas """
order of indices: (row_idx, col_idx) -not- (col_idx, row_idx)~(x,y)
same convention as numpy/pandas"""

# check for out of bounds (num_rows, num_cols) of grid
if row_idx < 0 or (row_idx > self.num_rows):
Expand All @@ -106,16 +115,15 @@ def cell_at(self, row_idx: int, col_idx: int) -> Optional[Cell]:
return None
row = self.rows[row_idx]


if col_idx > len(row):
return None
cell = row[col_idx]
return cell

# -------------------------------
def step(self, row_idx: int, col_idx: int) -> bool:
""" turn cell at given posn (col_idx,row_idx) black, merge any clusters.
return whether true if percolation has occured in this step """
"""turn cell at given posn (col_idx,row_idx) black, merge any clusters.
return whether true if percolation has occured in this step"""

cell = self.cell_at(row_idx, col_idx)
if cell is None:
Expand All @@ -129,14 +137,13 @@ def step(self, row_idx: int, col_idx: int) -> bool:
cell.cluster = cluster
self.clusters.add(cluster)


adjacent_cells = self.cells_adjacent_to(row_idx, col_idx)
if adjacent_cells is None:
return False

for cell_a in adjacent_cells:
if cell_a.is_black:
cluster_a = cell_a.cluster
cluster_a = cell_a.cluster
self.merge_clusters(cluster, cluster_a)

perc = cluster.percolates()
Expand All @@ -148,14 +155,14 @@ def step(self, row_idx: int, col_idx: int) -> bool:

# -------------------------------
def merge_clusters(self, cla: Cluster, clb: Optional[Cluster]):
""" merge any clusters.
return whether true if percolation has occurred in this step """
"""merge any clusters.
return whether true if percolation has occurred in this step"""

if (clb is None) or (cla is clb):
return

cla.merge(clb)
if (not clb in self.clusters):
if not clb in self.clusters:
halt = 1
self.clusters.remove(clb)
halt=1
halt = 1
Loading

0 comments on commit a923869

Please sign in to comment.