Repository: ShawHahnLab/igseq

Issue:
tree color-coding crashes when exactly one set is defined
When there's exactly one set of sequences defined, `make_seq_set_colors` crashes:

```
$ igseq tree -P '.*' --input-format newick <(echo '((A:1,B:1):1)') out.nex
$ igseq tree -P A --input-format newick <(echo '((A:1,B:1):1)') out.nex
Traceback (most recent call last):
  File "/home/jesse/miniconda3/envs/igseqhelper/bin/igseq", line 10, in <module>
    sys.exit(main())
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/__main__.py", line 89, in main
    args.func(args)
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/__main__.py", line 257, in _main_tree
    tree.tree(
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/tree.py", line 137, in tree
    seq_colors = color_seqs(seq_ids, seq_sets_combo, colors)
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/tree.py", line 296, in color_seqs
    seq_set_colors_combo = make_seq_set_colors(seq_sets)
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/tree.py", line 317, in make_seq_set_colors
    subset = [int( a * (num-1) / (len(seq_sets)-1) ) for a in range(num)]
  File "/home/jesse/miniconda3/envs/igseqhelper/lib/python3.9/site-packages/igseq/tree.py", line 317, in <listcomp>
    subset = [int( a * (num-1) / (len(seq_sets)-1) ) for a in range(num)]
ZeroDivisionError: division by zero
```

Comments:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18d86e2..543636d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # Changelog
 
+## dev
+
+### Fixed
+
+ * `tree` command can now handle assigning a color code when exactly one
+   sequence set is defined ([#57])
+
+[#57]: https://github.com/ShawHahnLab/igseq/pull/57
+
 ## 0.5.0 - 2023-01-04
 
 ### Added
diff --git a/igseq/tree.py b/igseq/tree.py
index 87f626c..713be55 100644
--- a/igseq/tree.py
+++ b/igseq/tree.py
@@ -314,7 +314,7 @@ def make_seq_set_colors(seq_sets):
         # adapted from SONAR
         # this stretches across COLORS in even increments for as many as we need here
         num = len(colors.COLORS)
-        subset = [int( a * (num-1) / (len(seq_sets)-1) ) for a in range(num)]
+        subset = [int( a * (num-1) / max(1, (len(seq_sets)-1)) ) for a in range(num)]
         try:
             seq_set_colors[set_name] = colors.color_str_to_trio(colors.COLORS[subset[idx]])
         except IndexError:


Test patch:
diff --git a/test_igseq/test_tree.py b/test_igseq/test_tree.py
index 2fcfd73..b987469 100644
--- a/test_igseq/test_tree.py
+++ b/test_igseq/test_tree.py
@@ -193,7 +193,7 @@ class TestParseLists(TestBase):
         self.assertEqual(tree.parse_lists(None), {})
 
 
-class TestParseColors(TestBase):
+class TestColors(TestBase):
 
     def test_parse_colors(self):
         # implicit naming
@@ -214,6 +214,19 @@ class TestParseColors(TestBase):
         # None should be equivalent to no colors given
         self.assertEqual(tree.parse_colors(None), {})
 
+    def test_make_seq_sets_colors(self):
+        # a basic scenario
+        self.assertEqual(
+            tree.make_seq_set_colors({"A": {"seq1", "seq2"}, "B": {"seq3", "seq4"}}),
+            {"A": [190, 66, 41], "B": [209, 134, 215]})
+        # just one set
+        self.assertEqual(
+            tree.make_seq_set_colors({"A": {"A"}}),
+            {"A": [190, 66, 41]})
+        # how about *no* sets?
+        self.assertEqual(tree.make_seq_set_colors({}), {})
+
+
 
 class TestLooksAligned(TestBase):