Skip to content

Commit 47101bf

Browse files
author
Release Manager
committed
gh-35466: refactor poset examples for better code coverage <!-- Please provide a concise, informative and self-explanatory title. --> <!-- Don't put issue numbers in the title. Put it in the Description below. --> <!-- For example, instead of "Fixes #12345", use "Add a new method to multiply two integers" --> ### 📚 Description This introduces in the file `poset_examples` an auxiliary function to check the input. This should help to increase the code coverage there. <!-- Describe your changes here in detail. --> <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x ]`. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #35466 Reported by: Frédéric Chapoton Reviewer(s): David Coudert
2 parents a6e2c32 + 67e7cf9 commit 47101bf

File tree

1 file changed

+73
-127
lines changed

1 file changed

+73
-127
lines changed

src/sage/combinat/posets/poset_examples.py

Lines changed: 73 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,51 @@
106106
from sage.categories.finite_lattice_posets import FiniteLatticePosets
107107
from sage.graphs.digraph import DiGraph
108108
from sage.rings.integer import Integer
109+
from sage.sets.non_negative_integers import NonNegativeIntegers
110+
111+
112+
def check_int(n, minimum=0):
113+
"""
114+
Check that ``n`` is an integer at least equal to ``minimum``.
115+
116+
This is a boilerplate function ensuring input safety.
117+
118+
INPUT:
119+
120+
- ``n`` -- anything
121+
122+
- ``minimum`` -- an optional integer (default: 0)
123+
124+
EXAMPLES::
125+
126+
sage: from sage.combinat.posets.poset_examples import check_int
127+
sage: check_int(6, 3)
128+
6
129+
sage: check_int(6)
130+
6
131+
132+
sage: check_int(-1)
133+
Traceback (most recent call last):
134+
...
135+
ValueError: number of elements must be a non-negative integer, not -1
136+
137+
sage: check_int(1, 3)
138+
Traceback (most recent call last):
139+
...
140+
ValueError: number of elements must be an integer at least 3, not 1
141+
142+
sage: check_int('junk')
143+
Traceback (most recent call last):
144+
...
145+
ValueError: number of elements must be a non-negative integer, not junk
146+
"""
147+
if minimum == 0:
148+
msg = "a non-negative integer"
149+
else:
150+
msg = f"an integer at least {minimum}"
151+
if n not in NonNegativeIntegers() or n < minimum:
152+
raise ValueError("number of elements must be " + msg + f", not {n}")
153+
return Integer(n)
109154

110155

111156
class Posets(metaclass=ClasscallMetaclass):
@@ -155,12 +200,7 @@ def __classcall__(cls, n=None):
155200
"""
156201
if n is None:
157202
return sage.categories.posets.Posets()
158-
try:
159-
n = Integer(n)
160-
except TypeError:
161-
raise TypeError("number of elements must be an integer, not {0}".format(n))
162-
if n < 0:
163-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
203+
n = check_int(n)
164204
return FinitePosets_n(n)
165205

166206
@staticmethod
@@ -203,12 +243,7 @@ def BooleanLattice(n, facade=None, use_subsets=False):
203243
sage: list(posets.BooleanLattice(1, use_subsets=True))
204244
[{}, {1}]
205245
"""
206-
try:
207-
n = Integer(n)
208-
except TypeError:
209-
raise TypeError("number of elements must be an integer, not {0}".format(n))
210-
if n < 0:
211-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
246+
n = check_int(n)
212247
if n == 0:
213248
if use_subsets:
214249
from sage.sets.set import Set
@@ -282,12 +317,7 @@ def ChainPoset(n, facade=None):
282317
sage: C.cover_relations()
283318
[[0, 1]]
284319
"""
285-
try:
286-
n = Integer(n)
287-
except TypeError:
288-
raise TypeError("number of elements must be an integer, not {0}".format(n))
289-
if n < 0:
290-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
320+
n = check_int(n)
291321
D = DiGraph([range(n), [[x, x + 1] for x in range(n - 1)]],
292322
format='vertices_and_edges')
293323
return FiniteLatticePoset(hasse_diagram=D,
@@ -335,12 +365,7 @@ def AntichainPoset(n, facade=None):
335365
sage: C.cover_relations()
336366
[]
337367
"""
338-
try:
339-
n = Integer(n)
340-
except TypeError:
341-
raise TypeError("number of elements must be an integer, not {0}".format(n))
342-
if n < 0:
343-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
368+
n = check_int(n)
344369
return Poset((range(n), []), facade=facade)
345370

346371
@staticmethod
@@ -398,12 +423,7 @@ def DiamondPoset(n, facade=None):
398423
sage: posets.DiamondPoset(7)
399424
Finite lattice containing 7 elements
400425
"""
401-
try:
402-
n = Integer(n)
403-
except TypeError:
404-
raise TypeError("number of elements must be an integer, not {0}".format(n))
405-
if n <= 2:
406-
raise ValueError("n must be an integer at least 3")
426+
n = check_int(n, 3)
407427
c = [[n - 1] for x in range(n)]
408428
c[0] = [x for x in range(1, n - 1)]
409429
c[n - 1] = []
@@ -435,12 +455,7 @@ def Crown(n, facade=None):
435455
sage: posets.Crown(3)
436456
Finite poset containing 6 elements
437457
"""
438-
try:
439-
n = Integer(n)
440-
except TypeError:
441-
raise TypeError("number of elements must be an integer, not {0}".format(n))
442-
if n < 2:
443-
raise ValueError("n must be an integer at least 2")
458+
n = check_int(n, 2)
444459
D = {i: [i + n, i + n + 1] for i in range(n - 1)}
445460
D[n - 1] = [n, n + n - 1]
446461
return FinitePoset(hasse_diagram=DiGraph(D), category=FinitePosets(),
@@ -478,12 +493,7 @@ def DivisorLattice(n, facade=None):
478493
Finite lattice containing 1 elements with distinguished linear extension
479494
"""
480495
from sage.arith.misc import divisors, is_prime
481-
try:
482-
n = Integer(n)
483-
except TypeError:
484-
raise TypeError("number of elements must be an integer, not {0}".format(n))
485-
if n <= 0:
486-
raise ValueError("n must be a positive integer")
496+
n = check_int(n, 1)
487497
Div_n = divisors(n)
488498
hasse = DiGraph([Div_n, lambda a, b: b % a == 0 and is_prime(b // a)])
489499
return FiniteLatticePoset(hasse, elements=Div_n, facade=facade,
@@ -623,9 +633,7 @@ def IntegerPartitionsDominanceOrder(n):
623633
[[4, 2], [5, 1]],
624634
[[5, 1], [6]]]
625635
"""
626-
from sage.rings.semirings.non_negative_integer_semiring import NN
627-
if n not in NN:
628-
raise ValueError('n must be an integer')
636+
n = check_int(n)
629637
from sage.combinat.partition import Partitions, Partition
630638
return LatticePoset((Partitions(n), Partition.dominates)).dual()
631639

@@ -663,14 +671,7 @@ def PowerPoset(n):
663671
0
664672
"""
665673
# Todo: Make this faster.
666-
667-
try:
668-
n = Integer(n)
669-
except TypeError:
670-
raise TypeError("parameter n must be an integer, not {0}".format(n))
671-
if n < 0:
672-
raise ValueError("parameter n must be non-negative, not {0}".format(n))
673-
674+
n = check_int(n)
674675
all_pos_n = set()
675676
Pn = list(Posets(n))
676677
for P in Pn:
@@ -759,16 +760,6 @@ def RandomPoset(n, p):
759760
760761
TESTS::
761762
762-
sage: posets.RandomPoset('junk', 0.5)
763-
Traceback (most recent call last):
764-
...
765-
TypeError: number of elements must be an integer, not junk
766-
767-
sage: posets.RandomPoset(-6, 0.5)
768-
Traceback (most recent call last):
769-
...
770-
ValueError: number of elements must be non-negative, not -6
771-
772763
sage: posets.RandomPoset(6, 'garbage')
773764
Traceback (most recent call last):
774765
...
@@ -783,13 +774,7 @@ def RandomPoset(n, p):
783774
Finite poset containing 0 elements
784775
"""
785776
from sage.misc.prandom import random
786-
787-
try:
788-
n = Integer(n)
789-
except (TypeError, ValueError):
790-
raise TypeError("number of elements must be an integer, not {0}".format(n))
791-
if n < 0:
792-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
777+
n = check_int(n)
793778
try:
794779
p = float(p)
795780
except (TypeError, ValueError):
@@ -856,16 +841,6 @@ def RandomLattice(n, p, properties=None):
856841
857842
TESTS::
858843
859-
sage: posets.RandomLattice('junk', 0.5)
860-
Traceback (most recent call last):
861-
...
862-
TypeError: number of elements must be an integer, not junk
863-
864-
sage: posets.RandomLattice(-6, 0.5)
865-
Traceback (most recent call last):
866-
...
867-
ValueError: number of elements must be non-negative, not -6
868-
869844
sage: posets.RandomLattice(6, 'garbage')
870845
Traceback (most recent call last):
871846
...
@@ -885,13 +860,7 @@ def RandomLattice(n, p, properties=None):
885860
Finite lattice containing 0 elements
886861
"""
887862
from copy import copy
888-
889-
try:
890-
n = Integer(n)
891-
except TypeError:
892-
raise TypeError("number of elements must be an integer, not {0}".format(n))
893-
if n < 0:
894-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
863+
n = check_int(n)
895864
try:
896865
p = float(p)
897866
except Exception:
@@ -973,10 +942,8 @@ def SetPartitions(n):
973942
sage: posets.SetPartitions(4)
974943
Finite lattice containing 15 elements
975944
"""
976-
from sage.rings.semirings.non_negative_integer_semiring import NN
977-
if n not in NN:
978-
raise ValueError('n must be an integer')
979945
from sage.combinat.set_partition import SetPartitions
946+
n = check_int(n)
980947
S = SetPartitions(n)
981948

982949
def covers(x):
@@ -1083,12 +1050,7 @@ def StandardExample(n, facade=None):
10831050
sage: P(4) < P(3), P(4) > P(3)
10841051
(False, False)
10851052
"""
1086-
try:
1087-
n = Integer(n)
1088-
except TypeError:
1089-
raise TypeError("dimension must be an integer, not {0}".format(n))
1090-
if n < 2:
1091-
raise ValueError("dimension must be at least 2, not {0}".format(n))
1053+
n = check_int(n, 2)
10921054
return Poset((range(2*n), [[i, j+n] for i in range(n)
10931055
for j in range(n) if i != j]),
10941056
facade=facade)
@@ -1244,17 +1206,20 @@ def TetrahedralPoset(n, *colors, **labels):
12441206
sage: tet = posets.TetrahedralPoset(3, 'green','yellow','blue','orange')
12451207
sage: ji.is_isomorphic(tet)
12461208
True
1209+
1210+
TESTS::
1211+
1212+
sage: posets.TetrahedralPoset(4,'scarlet')
1213+
Traceback (most recent call last):
1214+
...
1215+
ValueError: color input must be among: 'green', 'red', 'yellow',
1216+
'orange', 'silver', and 'blue'
12471217
"""
1218+
n = check_int(n, 2)
12481219
n = n - 1
1249-
try:
1250-
n = Integer(n)
1251-
except TypeError:
1252-
raise TypeError("n must be an integer")
1253-
if n < 2:
1254-
raise ValueError("n must be greater than 2")
12551220
for c in colors:
12561221
if c not in ('green', 'red', 'yellow', 'orange', 'silver', 'blue'):
1257-
raise ValueError("color input must be from the following: 'green', 'red', 'yellow', 'orange', 'silver', and 'blue'")
1222+
raise ValueError("color input must be among: 'green', 'red', 'yellow', 'orange', 'silver', and 'blue'")
12581223
elem = [(i, j, k) for i in range(n)
12591224
for j in range(n - i) for k in range(n - i - j)]
12601225
rels = []
@@ -1421,12 +1386,7 @@ def UpDownPoset(n, m=1):
14211386
sage: P = posets.UpDownPoset(0); P
14221387
Finite poset containing 0 elements
14231388
"""
1424-
try:
1425-
n = Integer(n)
1426-
except TypeError:
1427-
raise TypeError("number of elements must be an integer, not {0}".format(n))
1428-
if n < 0:
1429-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
1389+
n = check_int(n)
14301390
try:
14311391
m = Integer(m)
14321392
except TypeError:
@@ -1581,12 +1541,7 @@ def YoungFibonacci(n):
15811541
from sage.categories.finite_posets import FinitePosets
15821542
from sage.combinat.words.word import Word
15831543

1584-
try:
1585-
n = Integer(n)
1586-
except TypeError:
1587-
raise TypeError("number of elements must be an integer, not {0}".format(n))
1588-
if n < 0:
1589-
raise ValueError("number of elements must be non-negative, not {0}".format(n))
1544+
n = check_int(n)
15901545

15911546
if n == 0:
15921547
return MeetSemilattice({'': []})
@@ -1632,12 +1587,7 @@ def DoubleTailedDiamond(n):
16321587
sage: P.cover_relations()
16331588
[[1, 2], [2, 3], [2, 4], [3, 5], [4, 5], [5, 6]]
16341589
"""
1635-
try:
1636-
n = Integer(n)
1637-
except TypeError:
1638-
raise TypeError("number of elements must be an integer, not {}".format(n))
1639-
if n <= 0:
1640-
raise ValueError("number of elements must be nonnegative, not {}".format(n))
1590+
n = check_int(n, 1)
16411591

16421592
edges = [(i, i+1) for i in range(1, n)]
16431593
edges.extend([(n, n+1), (n, n+2), (n+1, n+3), (n+2, n+3)])
@@ -1680,12 +1630,7 @@ def PermutationPattern(n):
16801630
sage: posets.PermutationPattern(2)
16811631
Finite poset containing 3 elements
16821632
"""
1683-
try:
1684-
n = Integer(n)
1685-
except TypeError:
1686-
raise TypeError("number of elements must be an integer, not {}".format(n))
1687-
if n <= 0:
1688-
raise ValueError("number of elements must be nonnegative, not {}".format(n))
1633+
n = check_int(n, 1)
16891634
elem = []
16901635
for i in range(1, n + 1):
16911636
elem += Permutations(i)
@@ -1841,6 +1786,7 @@ def RibbonPoset(n, descents):
18411786
sage: sorted(R.cover_relations())
18421787
[[0, 1], [2, 1], [3, 2], [3, 4]]
18431788
"""
1789+
n = check_int(n)
18441790
return Mobile(DiGraph([list(range(n)),
18451791
[(i + 1, i) if i in descents else (i, i + 1)
18461792
for i in range(n - 1)]]))

0 commit comments

Comments
 (0)