With the latest changes, my repeat function no longer works with the lesser amount of image information I was previously saving. I would like to change that. I saved them for a reason. Perhaps regenerating them, even if not exactly like the original I was trying to save, is of value. So, let’s see if I can make them work with a reasonable amount of effort and refactoring.

Refactor Repeat Functionality for Missing Data

So we need to cope with missing data. I decided to add empty variables for any missing data to the dictionaries in the repeat module. And use their state, empty or not, to control what happens in other modules.

Udate repeats Module

I will just show the git diff for the first image data dictionary in the module. I added the commented out section so that I didn’t need to swap back and forth between files. It will be removed.

PS R:\learn\py_play\sp_fa> git diff repeats.py
diff --git a/repeats.py b/repeats.py
index 75f8a8c..9a83750 100644
--- a/repeats.py
+++ b/repeats.py
@@ -22,6 +22,11 @@ do_rpt = False
 do_nbr = 6
 d_rpt = []
 # ndx 0
+# g.cycle = r.d_rpt[r.do_nbr]['c_cyc']
+# g.alph = r.d_rpt[r.do_nbr]['c_lpha']
+# g.c_ndx = r.d_rpt[r.do_nbr]['c_ndx']
+# g.abg = r.d_rpt[r.do_nbr]['abg']
+# g.bg_lpha = r.d_rpt[r.do_nbr]['bg_lpha']
 d_rpt.append(
   {
     'i_typ': 'mosaic',
@@ -36,9 +41,12 @@ d_rpt.append(
     'cmap': 'PuRd',
     'c_nbr': '16',
     'c_cyc': [],
+    'c_lpha': None,
+    'c_ndx': None,
     'do_bg': 'true',
     'c_bg': 'RdPu',
     'abg': [],
+    'bg_lpha': None,
     'npts': 1024,
     'sz': 8,
     'dpi': 72,
@@ -46,6 +54,7 @@ d_rpt.append(
     'clw_pct': 'false',
     'clwc': '8',
     'clwpp': '12',
+    'm_inc': None,
     'ntr': 'r',
     'shp_mlt': 'false',
     'u_agn': 'false',

Refactor App Library Module

Next I went through the sp_app_lib module and tried to make changes that would account for the empty (missing) data values. Most of those were simply modifying previous if blocks dealing with the state of g.do_rpt.

Here’s the git diff for those changes.

PS R:\learn\py_play\sp_fa> git diff sp_app_lib.py
diff --git a/sp_app_lib.py b/sp_app_lib.py
index 1694996..e52c2ae 100644
--- a/sp_app_lib.py
+++ b/sp_app_lib.py
@@ -166,7 +166,7 @@ def btw_n_apart(axt, rxs, rys, dx=1, ol=True, r=False, fix=None, mlt=False, sect
   # between 0,0+dx ; 1,1+dx; etc
   c_ndx = 0
   c_len = len(g.cycle)
-  if not g.do_rpt:
+  if not g.do_rpt or not g.c_ndx:
     c_ndx = rng.integers(0, c_len-2)
     g.c_ndx = c_ndx
   else:
@@ -174,7 +174,7 @@ def btw_n_apart(axt, rxs, rys, dx=1, ol=True, r=False, fix=None, mlt=False, sect
   c_jmp = c_len // 20
   if c_jmp % 2 == 0:
     c_jmp += 1
-  if not g.do_rpt:
+  if not g.do_rpt or not g.alph:
     l_alph = 1
     g.alph = 1
   else:
@@ -1369,7 +1369,7 @@ def proc_curve_form(f_data, i_typ):
     g.bg_cmnm = g.rcm
     g.bg_cmap = bgcm_mpl[g.rcm]

-  if not g.do_rpt:
+  if not g.do_rpt or not g.bg_lpha:
     if "tab" in g.bg_cmnm or g.bg_cmnm == 'default':
       g.bg_lpha = rng.integers(5, 15) / 100
     else:
@@ -1534,7 +1534,7 @@ def set_bg(axb):
     # baxt, abg = blotch_bg_2(axb, extent=(xmin, xmax, ymin, ymax), dim=g.bb2_dim, cmap=g.bg_cmap, alpha=g.bg_lpha)
     #  no work -> baxt, abg = blotch_bg_2(axb, extent=(0, 1, 0, 1), transform=fig.transFigure, dim=g.bb2_dim, cmap=g.bg_cmap, alpha=g.bg_lpha)
     # baxt, abg = blotch_bg_2(axi, extent=(xmin, xmax, ymin, ymax), dim=g.bb2_dim, cmap=g.bg_cmap, alpha=g.bg_lpha, zorder=1)
-    if not g.do_rpt:
+    if not g.do_rpt or not g.abg:
       baxt, abg = blotch_bg_2(axb, extent=(0, 1, 0, 1), dim=g.bb2_dim, cmap=g.bg_cmap, alpha=g.bg_lpha, transform=axb.transAxes, zorder=1, aspect='auto')
     else:
       baxt, abg = blotch_bg_2(axb, extent=(0, 1, 0, 1), abg=g.abg, dim=g.bb2_dim, cmap=g.bg_cmap, alpha=g.bg_lpha, transform=axb.transAxes, zorder=1, aspect='auto')
@@ -1560,7 +1560,7 @@ def set_clr_map(ax, n_vals=None, cc=None):
     n_vals = 16
   c_rng = n_vals // 2

-  if not g.do_rpt:
+  if not g.do_rpt or not g.cycle:
     if u_cmap in ['default', 'tab20', 'tab20c', 'twilight_shifted']:
       c_cycle = [bgcm_mpl[u_cmap](i) for i in np.linspace(0, 1, n_vals+1)][:-1]
     else:

Refactor Main Module

I in fact initially did not add the code for the gnarly image type. But, when I tried adding a gnarly type image to the repeats module, the error messages had me sorting that out rather quickly.

PS R:\learn\py_play\sp_fa> git diff main.py
diff --git a/main.py b/main.py
index f104172..acaa481 100644
--- a/main.py
+++ b/main.py
@@ -891,6 +891,8 @@ def set_rpt_data():
   g.r_hts = [max(np.real(rd), np.imag(rd)) for rd in g.hts]
   # get the actually frequencies and congruency
   g.freqs = r.d_rpt[r.do_nbr]['freqs']
+  # deal with the new repeat data values
+  # following should be None or [] if not available
   g.cycle = r.d_rpt[r.do_nbr]['c_cyc']
   g.alph = r.d_rpt[r.do_nbr]['c_lpha']
   g.c_ndx = r.d_rpt[r.do_nbr]['c_ndx']
@@ -905,16 +907,17 @@ def set_rpt_data():

 @ -923,11 +926,16 @@ def sp_repeat():
       sal.btw_n_apart(ax, r_xs, r_ys, dx=g.bw_dx, ol=g.bw_o, r=g.bw_r, fix=None, mlt=g.bw_m, sect=g.bw_s)
     elif r.d_rpt[r.do_nbr]['i_typ'] == 'clw_btw':
       h_cyc, mn_mlt, mx_mlt, m_inc, n_max, pp_clr = sal.cycle_lw_btw(ax, r_xs[-1], r_ys[-1], u_pcnt=g.use_pct, n_cyc=g.n_lwcyc, dppc=g.dpp_clr)
+    elif  r.d_rpt[r.do_nbr]['i_typ'] == 'gnarly':
+      ax.plot(r_xs, r_ys, lw=g.ln_w, alpha=g.alph, zorder=g.pz_ord)
+      ax.plot(m_xs, m_ys, lw=g.ln_w, alpha=g.alph, zorder=g.pz_ord)
+      ax.plot(m2_xs, m2_ys, lw=g.ln_w, alpha=g.alph, zorder=g.pz_ord)

     # # if is_dev:
     # #   print(f"bg A: {g.abg}")
@@ -958,6 +966,11 @@ def sp_repeat():
                 'hf_frq': h_cyc, 'n_max': n_max, 'pp_clr': pp_clr,
                 'u_pct': g.use_pct, 'n_lwc': g.n_lwcyc
                 }
+    elif r.d_rpt[r.do_nbr]['i_typ'] == 'gnarly':
+      d_end = "top" if g.drp_f else "bottom"
+      p_data = {
+        'd_end': d_end, 'd_nbr': g.r_skp
+      }

     g.do_rpt = False

Tests

The first 3 images in the repeats module did not have the main and background colour information. Here’s what the repeat route generated for the first one.

using repeat route to reproduce a mosaic style spirograpn lacking the extra colour information
A "repeated" mosaic image w/o extra colour information.

Of course, every time I repeat this one, the colour patterns will change. But, if I get one I really like, I can save the extra information and add it the images data dictionary.

And, here’s one I saved long ago. It is also missing a goodly amount of information. It’s the gnarly type that generated the error messages mentioned above leading to the refactoring the repeat routes function.

using repeat route to reproduce a gnarly style spirograpn lacking the extra colour information
A "repeated" gnarly image w/o extra colour information.

More Refactoring

Doing the above test with the earlier gnarly type spirograph, I had one other problem. One I did not address in the changes documented above. I did not from the start have coloured backgrounds, they were added later. So for the last image above, I just assigned a background colour map. What I would actually prefer is that if no background colour map is assigned, then one should be randomly selected from those allowed for the spirograph’s colour map.

Rather Simple

A simple change for the repeats module. For each affected image, just set 'c_bg': None,. And in proc_curve_form() in the app library module make the following change (git diff shown). Note, g.use_rand_bg defaults to True.

PS R:\learn\py_play\sp_fa> git diff sp_app_lib.py
diff --git a/sp_app_lib.py b/sp_app_lib.py
index e52c2ae..8dcf81b 100644
--- a/sp_app_lib.py
+++ b/sp_app_lib.py
@@ -1356,10 +1356,8 @@ def proc_curve_form(f_data, i_typ):

   if 'do_bg' in f_data:
     g.use_bb2 = True if f_data['do_bg'] == 'true' else False

-  if g.do_rpt:
+  if g.do_rpt and r.d_rpt[r.do_nbr]['c_bg']:
     g.bg_cmnm = r.d_rpt[r.do_nbr]['c_bg']
     g.bg_cmap = bgcm_mpl[g.bg_cmnm]
   elif g.use_bb2 and g.use_rand_bg:

And, bingo. Wouldn’t bother adding any more images. You’ll have to take my word that it works as expected.

Done

I think that’s it for this one. I am quite pleased at getting these fixes done. And, so relatively painlessly.

May your refactoring efforts prove as painless.