18 from __future__
import print_function
21 VERSION =
'knots --- 2010 April 12'
23 import copy, functools, numbers
89 KNOTCHARS = EMPTY + LEFT + RIGHT + TOP + BOTTOM + UP + DOWN + VERT + HORI + CROSSUP + CROSSDOWN
92 LABELSTATECHARS = EMPTY + LEFT + RIGHT + TOP + BOTTOM + UP + DOWN + VERT + HORI \
93 + CROSSUPA + CROSSUPB + CROSSDOWNA + CROSSDOWNB
96 STATECHARS = EMPTY + LEFT + RIGHT + TOP + BOTTOM + UP + DOWN + VERT + HORI
99 UNIVERSECHARS = EMPTY + LEFT + RIGHT + TOP + BOTTOM + UP + DOWN + VERT + HORI + CROSS
106 SPACECHARS = KNOTCHARS + CROSSUPA + CROSSUPB + CROSSDOWNA + CROSSDOWNB + CROSS
115 CORNERS[EMPTY] = ((
None,
None),
117 CORNERS[LEFT] = (((0, 1),
None),
119 CORNERS[RIGHT] = ((
None, (0, 1)),
121 CORNERS[TOP] = (((1, 0), (-1, 0)),
123 CORNERS[BOTTOM] = ((
None,
None),
125 CORNERS[UP] = ((
None, (-1, 1)),
127 CORNERS[DOWN] = (((1, 1),
None),
129 CORNERS[CROSS] = (((1, 1), (-1, 1)),
131 CORNERS[CROSSUP] = CORNERS[CROSS]
132 CORNERS[CROSSDOWN] = CORNERS[CROSS]
134 CORNERS[VERT] = (((0, 1), (0, 1)),
136 CORNERS[HORI] = (((1, 0), (-1, 0)),
138 CORNERS[CROSSUPA] = CORNERS[VERT]
139 CORNERS[CROSSUPB] = CORNERS[HORI]
140 CORNERS[CROSSDOWNA] = CORNERS[HORI]
141 CORNERS[CROSSDOWNB] = CORNERS[VERT]
150 PRIMEKNOTS[0][1] = [
'()']
152 PRIMEKNOTS[3][1] = [
' /%\\',
156 PRIMEKNOTS[4][1] = [
' _',
162 PRIMEKNOTS[5][1] = [
' _',
166 PRIMEKNOTS[5][2] = [
' _',
172 PRIMEKNOTS[6][1] = [
' ___',
177 PRIMEKNOTS[6][2] = [
' _',
183 PRIMEKNOTS[6][2] = [
' _',
188 PRIMEKNOTS[6][3] = [
' _',
195 PRIMEKNOTS[7][1] = [
' _____',
204 BORROMEAN = [
' /&\\',
218 """Modifie l'espace s en lui ajoutant l'espace a à droite
230 for y
in range(min(len(s), len(a))):
231 m = max(m, len(s[y]))
232 for y
in range(min(len(s), len(a))):
233 s[y] += EMPTY*(m - len(s[y])) + a[y]
235 for y
in range(len(s), len(a)):
236 s.append(EMPTY*m + a[y])
241 """Renvoie True si tous les cycles de l'espace s sont fermés,
252 for line
in s + [
'']:
253 line_src = line + EMPTY
254 if len(prev) > len(line):
255 line += EMPTY * (len(prev) - len(line))
256 elif len(prev) < len(line):
257 prev += EMPTY * (len(line) - len(prev))
260 for i
in range(len(line)):
264 nb = ((CORNERS[prev_c][1][1] !=
None) + (CORNERS[prev[i]][1][0] !=
None)
265 + (CORNERS[line_c][0][1] !=
None) + (CORNERS[line[i]][0][0] !=
None))
266 if (nb != 0)
and (nb != 2):
267 assert nb == 1, (i, nb, line)
278 """Renvoie True si l'espace s est de type knots
279 (un espace vide ou contenant des noeuds),
294 """Renvoie la liste ordonnée des combinaisons possibles de labels A et B
296 (Si nb == 0 alors renvoie ['']
297 Si nb == 1 alors renvoie ['A', 'B']
298 Si nb == 2 alors renvoie ['AA', 'AB', 'BA', 'BB']
299 Si nb == 2 alors renvoie ['AAA', 'AAB', 'ABA', 'ABB',
300 'BAA', 'BAB', 'BBA', 'BBB']
305 Result: liste de 2**n string de 'A' et 'B' de longueur n
322 """Renvoie True si l'espace s est de type labelstates
323 (un espace vide ou contenant des états labellisés de noeuds),
333 if not isinstance(s, list):
336 if not isinstance(line, str):
339 if c
not in LABELSTATECHARS:
346 """Renvoie True si l'espace s est de type links
347 (un espace vide ou contenant des liens),
357 if not isinstance(s, list):
360 if not isinstance(line, str):
363 if c
not in KNOTCHARS:
371 """ Modifie l'espace s pour que toutes les lignes aient même longueur
372 en ajoutant des add à droite
373 !!! Le résultat n'est pas forcément un space
376 add: caractère de SPACECHARS
382 assert isinstance(add, str), add
383 assert len(add) == 1, add
384 assert add
in SPACECHARS, add
386 m = functools.reduce(
lambda m, line: max(m, len(line)), s, 0)
387 for y
in range(len(s)):
388 s[y] += add*(m - len(s[y]))
393 """Renvoie l'image miroir de l'espace s
407 CONV[BOTTOM] = BOTTOM
412 CONV[CROSSUP] = CROSSDOWN
413 CONV[CROSSDOWN] = CROSSUP
414 CONV[CROSSUPA] = CROSSDOWNA
415 CONV[CROSSDOWNA] = CROSSUPA
416 CONV[CROSSUPB] = CROSSDOWNB
417 CONV[CROSSDOWNB] = CROSSUPB
434 """Renvoie le nombre d'états A (croisements up ou down)
435 de l'espace d'états labellisés s
444 return nb_items(s, CROSSUPA + CROSSDOWNA)
449 """Renvoie le nombre d'états B (croisements up ou down)
450 de l'espace d'états labellisés s
459 return nb_items(s, CROSSUPB + CROSSDOWNB)
465 """Renvoie le nombre de croisements (up, down ou non "orientés")
466 et d'états de croisements labellisés de l'espace s
475 return nb_items(s, CROSSUP + CROSSDOWN + CROSSUPA + CROSSUPB + CROSSDOWNA + CROSSDOWNB + CROSS)
480 """Renvoie (nombre de cycles, nombre de cycles ouverts) de l'espace s
484 Result: (naturel, naturel)
494 """Renvoie le nombre d'éléments de l'espace s qui sont dans items
497 items: string de caractères appartenant à SPACECHARS
503 assert isinstance(items, str), items
506 assert c
in SPACECHARS, (c, items)
519 """Renvoie le polynôme invariant de Kauffman pour l'espace de noeuds s,
520 c.-à-d. (-A^(-3))^writhe(s) * poly_Kauffman_A(s)
521 (invariant pour les isotopies :
522 mouvements 0, I, II et III de Reidemeister)
524 Pre: s: knots non vide
532 assert nb[0] > 0, nb[0]
533 assert nb[1] == 0, nb[1]
549 """Renvoie le polynôme A de Kauffman pour l'espace de noeuds s,
550 c.-à-d. le polynôme ABd de Kauffman avec B = A^-1 et d = -A^2 - A^-2
551 (invariant pour les isotopies régulières :
552 mouvements 0, II et III de Reidemeister)
554 Pre: s: knots non vide
562 assert nb[0] > 0, nb[0]
563 assert nb[1] == 0, nb[1]
570 sign = (1
if d_e%2 == 0
572 for i
in range(d_e + 1):
573 p.__iadd__(
polynomial.Term((e + i*4, )), coef=natural.binom(d_e, i)*sign)
579 """Renvoie le polynôme ABd de Kauffman pour l'espace de noeuds s
580 = somme sur tous les états labellisés de s
581 du produit des labels A et B
582 et de d^(nombre de cycles fermés - 1) de l'état
601 """Renvoie le noeud premier n_1
603 Pre: n: naturel pair >= 4
612 ' /%' +
' '*n +
'\\',
614 ' \\%' +
' '*n +
'/',
621 """Renvoie l'espace lu dans le fichier f
623 Pre: f: fichier (texte) ouvert en lecture
625 Result: list de string (qui n'est pas forcément un space !!!)
630 l = f.read().splitlines()
640 """Renvoie l'espace s avec une rotation de nb*90°
641 dans le sens anti-horloger
650 assert isinstance(nb, numbers.Integral), nb
662 CONV[CROSSUP] = CROSSDOWN
663 CONV[CROSSDOWN] = CROSSUP
664 CONV[CROSSUPA] = CROSSDOWNA
665 CONV[CROSSDOWNA] = CROSSUPA
666 CONV[CROSSUPB] = CROSSDOWNB
667 CONV[CROSSDOWNB] = CROSSUPB
671 m = functools.reduce(
lambda m, line: max(m, len(line)), s, 0)
674 for y
in range(len(s)):
675 line = s[y] + EMPTY*(m - len(s[y]))
676 for x
in range(len(line)):
677 r[m - 1 - x] += CONV[line[x]]
689 """Renvoie True si s est de type space
690 (un espace vide ou contenant des noeuds,
691 états de noeuds (labellisés ou non) et univers de noeuds),
694 Pre: s: object quelconque
699 if not isinstance(s, list):
702 for line
in s + [
'']:
703 if not isinstance(line, str):
705 line_src = line + EMPTY
706 if len(prev) > len(line):
707 line += EMPTY * (len(prev) - len(line))
708 elif len(prev) < len(line):
709 prev += EMPTY * (len(line) - len(prev))
712 if line_c
not in SPACECHARS:
714 for i
in range(len(line)):
715 if line[i]
not in SPACECHARS:
720 nb = ((CORNERS[prev_c][1][1] !=
None) + (CORNERS[prev[i]][1][0] !=
None)
721 + (CORNERS[line_c][0][1] !=
None) + (CORNERS[line[i]][0][0] !=
None))
732 """Renvoie True si l'espace s est de type states
733 (un espace vide ou contenant des états non labellisés de noeuds),
743 if not isinstance(s, list):
746 if not isinstance(line, str):
749 if c
not in STATECHARS:
756 """Renvoie l'état labellisé de l'espace s de noeuds ou d'états labellisés
757 Le parcours de s se fait de la gauche vers la droite,
759 Chaque croisement est alors remplacé par son état labellisé
760 en fonction du 'A' ou 'B' dans labels.
761 Lorsque les caractères de labels sont épuisés,
762 c'est l'état A qui est choisi.
764 Pre: s: knots ou labelstates
765 (ou space mélange des deux,
766 mais ne contenant pas d'état non labellisé
767 ou de croisement non "orienté")
768 labels: string de 'A' et 'B'
781 if c
in CROSSUP + CROSSUPA + CROSSUPB :
782 new_line += (CROSSUPA
if (labels ==
'')
or (labels[0] ==
'A')
785 elif c
in CROSSDOWN + CROSSDOWNA + CROSSDOWNB:
786 new_line += (CROSSDOWNA
if (labels ==
'')
or (labels[0] ==
'A')
791 new_s.append(new_line)
803 def to_LaTeX(s, length=None, shape=None, grid=None):
804 """Renvoie un string contenant le code LaTeX
805 (pour le module Knots.sty :
806 http://www.opimedia.be/DS/DSPython/)
807 de la représentation de l'espace s
808 length : taille du quadrillage
809 (si None alors utilise la valeur de Knots.sty : par défaut 20)
810 shape : détermine la forme des arrondis
811 (si None alors utilise la valeur de Knots.sty : par défaut 5)
812 grid : Si True alors affiche le quadrillage, sinon pas
814 alors utilise la valeur de Knots.sty : par défaut False)
817 length: None ou naturel > 0
818 shape: None ou naturel > 0
819 grid: None ou boolean
826 assert length ==
None or length > 0, length
828 assert shape ==
None or shape > 0, shape
830 r = [
'\\Knots{{{0}}}{{{1}}}{{%\n'
831 .format(functools.reduce(
lambda m, line: max(m, len(line)), s, 0),
835 r.append(
' \\setcounter{{Knotslen}}{0}%\n'.format(length))
837 r.append(
' \\setcounter{{Knotsshape}}{{\\theKnotslen/{0}}}%\n'.format(shape))
839 r.append(
' \\Kgridtrue\n' if grid
840 else ' \\Kgridfalse\n')
852 CONV[CROSSUP] =
r'\%'
853 CONV[CROSSDOWN] =
r'\&'
854 CONV[CROSSUPA] =
r'\A'
855 CONV[CROSSUPB] =
r'\B'
856 CONV[CROSSDOWNA] =
r'\a'
857 CONV[CROSSDOWNB] =
r'\b'
870 def to_PS(s, length=30, margin=10, shape=5, grid=False):
871 """Renvoie un string contenant le code PostScript
872 de la représentation de l'espace s
873 length : taille du quadrillage
874 margin : taille des marges
875 shape : détermine la forme des arrondis
876 grid : Si True alors affiche le quadrillage, sinon pas
889 assert length > 0, length
891 assert isinstance(shape, numbers.Real), shape
892 assert shape != 0, shape
894 grid = (
'true' if grid
897 r = [
"""%!PS-Adobe-3.0 EPSF-3.0
898 %%BoundingBox: 0 0 {0} {1}
899 """.format(functools.reduce(
lambda m, line: max(m, len(line)), s, 0)*length + margin*2,
900 len(s)*length + margin*2),
901 """%%Creator: DSPython --- http://www.opimedia.be/DS/DSPython/
913 x len add y shape add
928 len 1.9 mul 5 div dup rlineto
929 len 1.2 mul 5 div dup rmoveto
930 len 1.9 mul 5 div dup rlineto
942 len 2 div shape .8 mul rmoveto
943 0 len shape 1.6 mul sub rlineto
948 len size sub 2 div dup len sub rmoveto
958 shape .8 mul len 2 div rmoveto
959 len shape 1.6 mul sub 0 rlineto
964 len size sub 2 div dup exch len sub exch rmoveto
972 len 1.9 mul 5 div neg dup neg rlineto
973 len 1.2 mul 5 div neg dup neg rmoveto
974 len 1.9 mul 5 div neg dup neg rlineto
984 shape .8 mul len 2 div rmoveto
985 len shape 1.6 mul sub 0 rlineto
990 len size sub 2 div dup exch len sub exch rmoveto
1000 len 2 div shape .8 mul rmoveto
1001 0 len shape 1.6 mul sub rlineto
1006 len size sub 2 div dup len sub rmoveto
1011 grid { lightbox } if
1027 grid { lightbox } if
1035 grid { lightbox } if
1041 x shape add y len add
1056 grid { lightbox } if
1063 x shape sub y len add
1069 grid { lightbox } if
1076 x len add y shape sub
1082 grid { lightbox } if
1088 grid { lightbox } if
1095 % Variables globales
1096 %%%%%%%%%%%%%%%%%%%%%
1098 """/grid {0} def % si true alors affiche les cadres en gris, sinon ne les affiche pas
1099 /len {1} def % taille des cadres
1100 /shape len {2} div def % taille pour l'arrondi
1101 """.format(grid, length, shape),
1102 """/size len 2 div 1.5 div def % taille de la police de caracteres
1106 /Times-Roman findfont
1107 size 1.5 mul scalefont
1114 CONV[EMPTY] =
'grid { lightbox } if'
1116 CONV[RIGHT] =
'right'
1118 CONV[BOTTOM] =
'bottom'
1123 CONV[CROSSUP] =
'crossup'
1124 CONV[CROSSDOWN] =
'crossdown'
1125 CONV[CROSSUPA] =
'crossupA'
1126 CONV[CROSSUPB] =
'crossupB'
1127 CONV[CROSSDOWNA] =
'crossdownA'
1128 CONV[CROSSDOWNB] =
'crossdownB'
1129 CONV[CROSS] =
'cross'
1131 y = len(s)*length + margin
1136 r.append(
'{0} {1} moveto '.format(x, y) + CONV[c] +
'\n')
1139 r.append(
"""showpage
1147 """Renvoie l'état non labellisé de l'espace s
1148 de noeuds ou d'états (labellisés ou non).
1149 Le parcours de s se fait de la gauche vers la droite,
1150 du haut vers le bas.
1151 Chaque croisement est alors remplacé par son état non labellisé
1152 en fonction du 'A' ou 'B' dans labels.
1153 Lorsque les caractères de labels sont épuisés,
1154 c'est l'état A qui est choisi.
1156 Pre: s: noeuds, labelstates ou states
1157 (ou space mélange des trois,
1158 mais ne contenant pas de croisement non "orienté")
1159 labels: string de 'A' et 'B'
1172 if c
in CROSSUP + CROSSUPA + CROSSUPB :
1173 new_line += (VERT
if (labels ==
'')
or (labels[0] ==
'A')
1176 elif c
in CROSSDOWN + CROSSDOWNA + CROSSDOWNB:
1177 new_line += (HORI
if (labels ==
'')
or (labels[0] ==
'A')
1182 new_s.append(new_line)
1188 """Renvoie l'espace s dans un string avec retour à la ligne
1202 """Renvoie l'univers des noeuds de l'espace s
1215 new_line += (CROSS
if c
in CROSSUP + CROSSDOWN + CROSSUPA + CROSSUPB
1216 + CROSSDOWNA + CROSSDOWNB
1218 new_s.append(new_line)
1224 """Renvoie True si l'espace s est de type universes
1225 (un espace vide ou contenant des univers de noeud),
1235 if not isinstance(s, list):
1238 if not isinstance(line, str):
1241 if c
not in UNIVERSECHARS:
1248 """Écrit l'espace s dans le fichier f
1250 Pre: f: fichier (texte) ouvert en écriture
1259 f.writelines([l +
'\n' for l
in s])
1264 """Renvoie le degré de torsion du space s,
1265 c.-à-d. la somme des degrés de torsion pour tous ses croisements
1267 Pre: s: knots dont tous les croisements sont dans 1 ou 2 cycles fermés
1276 for y
in range(len(s)):
1278 for x
in range(len(line)):
1280 if (c == CROSSUP)
or (c == CROSSDOWN):
1281 w += a.writhe_cross(x, y, c == CROSSUP)
1287 """Renvoie le degré de torsion du croisement "orienté"
1288 placé en (x, y) du space s.
1289 Si les deux brins du croisement
1290 font partie de 2 cycles différents alors renvoie 0,
1291 sinon renvoie -1 ou 1.
1293 Pre: s: space tel que s[y][x] == CROSSUP ou CROSSDOWN
1294 dans 1 ou 2 cycles fermés
1304 assert s[y][x] == CROSSUP
or s[y][x] == CROSSDOWN, (x, y, s[y][x])
1316 """Tableau (list de list) "des coins" d'un space.
1317 Pour chaque coin, un list de couples (x, y) avec x et y == -1, 0 ou 1"""
1321 """Initialise le Corners à partir du space value
1330 nb = functools.reduce(
lambda m, line: max(m, len(line)),
1332 list.__init__(self, [
None] * (len(value) + 1))
1335 self[0] = [
None] * nb
1340 for y
in range(len(value)):
1342 self[y + 1] = [
None] * nb
1348 for x
in range(len(line)):
1349 c = CORNERS[line[x]]
1351 self[y][x].append(c[0][0])
1353 self[y][x + 1].append(c[0][1])
1355 self[y + 1][x].append(c[1][0])
1357 self[y + 1][x + 1].append(c[1][1])
1363 """Si le coin (x, y) est vide ou passe par un cycle fermé
1364 alors renvoie (x, y),
1365 sinon renvoie les coordonnées d'une extrémité
1366 du cycle ouvert passant par (x, y)
1371 Result: (naturel, naturel)
1378 add_x, add_y = self[y][x][0]
1379 moving_x = x + add_x
1380 moving_y = y + add_y
1381 while (moving_x != x
or moving_y != y)
and len(self[moving_y][moving_x]) != 1:
1382 assert len(self[moving_y][moving_x]) == 2, \
1383 (x, y, moving_x, moving_y, self[moving_y][moving_x])
1385 add_x, add_y = (self[moving_y][moving_x][
1387 1
if ((self[moving_y][moving_x][0][0] == -add_x)
1388 and (self[moving_y][moving_x][0][1] == -add_y))
1400 """Renvoie (nombre de cycles, nombre de cycles ouverts) du Corners
1402 Result: (naturel, naturel)
1405 a = copy.deepcopy(self)
1409 for y
in range(len(a)):
1410 for x
in range(len(a[y])):
1413 (x, y) = a.extremity(x, y)
1415 assert a[y][x] != [], (x, y)
1419 add_x, add_y = a[y][x][0]
1420 a[y][x] = a[y][x][1:]
1421 moving_x = x + add_x
1422 moving_y = y + add_y
1423 i = a[moving_y][moving_x].index((-add_x, -add_y))
1424 a[moving_y][moving_x] = a[moving_y][moving_x][:i] + a[moving_y][moving_x][i + 1:]
1425 while (moving_x != x
or moving_y != y)
and a[moving_y][moving_x] != []:
1426 add_x, add_y = a[moving_y][moving_x][0]
1427 a[moving_y][moving_x] = a[moving_y][moving_x][1:]
1430 i = a[moving_y][moving_x].index((-add_x, -add_y))
1431 a[moving_y][moving_x] = (a[moving_y][moving_x][:i]
1432 + a[moving_y][moving_x][i + 1:])
1433 if (moving_x == x)
and (moving_y == y):
1438 assert a[y][x] == [], (x, y, a[y][x])
1440 return (nb, nb_open)
1445 """Renvoie le degré de torsion du croisement "orienté"
1446 placé entre (x, y) et (x + 1, y + 1).
1447 Si les deux brins du croisement font partie
1448 de 2 cycles différents alors renvoie 0,
1449 sinon renvoie -1 ou 1.
1451 Pre: l'élément entre (x, y) et (x + 1, y + 1)
1452 est un CROSSUP si crossup == True
1453 ou un CROSSDOWN si crossup == False,
1454 faisant partie de 1 ou de 2 cycles fermés
1468 add_x, add_y = self[y][x][
1469 1
if self[y][x][0] == (1, 1)
1472 moving_x = x + add_x
1473 moving_y = y + add_y
1474 while not (0 <= moving_x - x <= 1
and 0 <= moving_y - y <= 1):
1475 assert len(self[moving_y][moving_x]) == 2, \
1476 (x, y, moving_x, moving_y, self[moving_y][moving_x])
1478 add_x, add_y = self[moving_y][moving_x][
1480 1
if ((self[moving_y][moving_x][0][0] == -add_x)
1481 and (self[moving_y][moving_x][0][1] == -add_y))
1486 add_x = moving_x - x
1487 add_y = moving_y - y
1489 assert add_x == 0
or add_x == 1, add_x
1490 assert add_y == 0
or add_y == 1, add_y
1491 assert add_x == 1
or add_y == 1, (add_x, add_y)
1493 if (add_x == 0)
or (add_y == 0):
1495 return (1
if add_x == 0
1498 return (-1
if add_x == 0
1508 if __name__ ==
'__main__':
1510 """Test du module"""
1511 import os, sys, tempfile
1514 if not 'profile' in dir():
1522 debug.test_begin(VERSION, __debug__)
1524 print(
"SPACECHARS == '{0}'".format(SPACECHARS)); sys.stdout.flush()
1525 for c
in SPACECHARS:
1526 assert 32 <= ord(c) <= 127, c
1528 print(
"KNOTCHARS == '{0}'".format(KNOTCHARS)); sys.stdout.flush()
1529 print(
"LABELSTATECHARS == '{0}'".format(LABELSTATECHARS)); sys.stdout.flush()
1530 print(
"STATECHARS == '{0}'".format(STATECHARS)); sys.stdout.flush()
1531 print(
"UNIVERSECHARS == '{0}'".format(UNIVERSECHARS)); sys.stdout.flush()
1534 print(
'CORNERS...', end=
''); sys.stdout.flush()
1535 assert len(CORNERS) == len(SPACECHARS), (len(CORNERS), len(SPACECHARS))
1536 for i
in SPACECHARS:
1537 assert isinstance(CORNERS[i], tuple)
1538 assert len(CORNERS[i]) == 2, (i, CORNERS[i])
1541 assert len(CORNERS[i][y]) == 2, (i, y, CORNERS[i][y])
1543 c = CORNERS[i][y][x]
1544 assert c ==
None or len(c) == 2, (i, y, x, c)
1546 assert c != (0, 0), (i, y, x, c)
1547 t = CORNERS[i][y + c[1]][x + c[0]]
1548 assert t[0] == -c[0], (i, y, x, c, t)
1549 assert t[1] == -c[1], (i, y, x, c, t)
1552 assert nb == 0, (i, nb, CORNERS[i])
1553 elif i
in (LEFT, RIGHT, TOP, BOTTOM, UP, DOWN):
1554 assert nb == 2, (i, nb, CORNERS[i])
1556 assert nb == 4, (i, nb, CORNERS[i])
1557 print(
'ok'); sys.stdout.flush()
1560 print(
'PRIMEKNOTS...', end=
''); sys.stdout.flush()
1561 assert isinstance(PRIMEKNOTS, dict)
1562 assert len(PRIMEKNOTS) == 6, len(PRIMEKNOTS)
1563 for nb
in PRIMEKNOTS:
1564 assert len(PRIMEKNOTS[nb]) >0, (nb, len(PRIMEKNOTS[nb]))
1565 for i
in PRIMEKNOTS[nb]:
1566 assert knots_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
1567 assert closed_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
1568 assert nb_cycle(PRIMEKNOTS[nb][i]) == (1, 0), \
1569 (nb, i,
nb_cycle(PRIMEKNOTS[nb][i]), PRIMEKNOTS[nb][i])
1570 print(
'ok'); sys.stdout.flush()
1573 print(
'BORROMEAN...', end=
''); sys.stdout.flush()
1574 assert knots_is(BORROMEAN), BORROMEAN
1577 print(
'ok'); sys.stdout.flush()
1581 print(
'addtoright()...', end=
''); sys.stdout.flush()
1585 s = [
' _',
'( )',
'^ ^']
1586 assert addtoright(s, [
'_',
'%',
'%',
'^']) ==
None
1587 assert s == [
' _ _',
'( )%',
'^ ^%',
' ^'], s
1589 for nb
in PRIMEKNOTS:
1590 for i
in PRIMEKNOTS[nb]:
1592 assert addtoright(s, PRIMEKNOTS[nb][i]) ==
None, (nb, i)
1593 assert s == PRIMEKNOTS[nb][i], (nb, i, s)
1595 assert addtoright(s, PRIMEKNOTS[nb][i]) ==
None, (nb, i)
1596 assert s == PRIMEKNOTS[nb][i], (nb, i, s)
1598 s += PRIMEKNOTS[nb][i]
1600 assert s == PRIMEKNOTS[nb][i], (nb, i, s)
1602 s += PRIMEKNOTS[nb][i]
1604 assert s == PRIMEKNOTS[nb][i], (nb, i, s)
1605 print(
'ok'); sys.stdout.flush()
1608 print(
'closed_is()...', end=
''); sys.stdout.flush()
1627 for c
in SPACECHARS:
1632 for nb
in PRIMEKNOTS:
1633 for i
in PRIMEKNOTS[nb]:
1634 assert closed_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
1639 (nb, i,
to_states(PRIMEKNOTS[nb][i], labels))
1642 print(
'ok'); sys.stdout.flush()
1645 print(
'knots_is()...', end=
''); sys.stdout.flush()
1650 for i
in range(256):
1654 for nb
in PRIMEKNOTS:
1655 for i
in PRIMEKNOTS[nb]:
1656 assert knots_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
1658 for i
in PRIMEKNOTS[nb]:
1661 (nb, i, labels, PRIMEKNOTS[nb][i],
1664 (nb, i, labels, PRIMEKNOTS[nb][i],
1667 (nb, i, PRIMEKNOTS[nb][i],
to_universes(PRIMEKNOTS[nb][i]))
1668 print(
'ok'); sys.stdout.flush()
1671 print(
'labels_list()...', end=
''); sys.stdout.flush()
1675 assert labels_list(3) == [
'AAA',
'AAB',
'ABA',
'ABB',
'BAA',
'BAB',
'BBA',
'BBB'], \
1679 assert len(l) == 2**n, (n, len(l))
1681 assert len(s) == n, (n, len(s))
1682 assert s.count(
'A') + s.count(
'B') == n, (n, s.count(
'A'), s.count(
'B'))
1683 print(
'ok'); sys.stdout.flush()
1686 print(
'labelstates_is()...', end=
''); sys.stdout.flush()
1689 for c
in LABELSTATECHARS:
1691 for i
in range(256):
1693 if c
in LABELSTATECHARS:
1695 for nb
in PRIMEKNOTS:
1696 for i
in PRIMEKNOTS[nb]:
1699 (nb, i, PRIMEKNOTS[nb][i],
1702 for i
in PRIMEKNOTS[nb]:
1703 assert not labelstates_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
1706 (nb, i, PRIMEKNOTS[nb][i],
1707 labels,
to_states(PRIMEKNOTS[nb][i], labels))
1710 print(
'ok'); sys.stdout.flush()
1713 print(
'links_is()...', end=
''); sys.stdout.flush()
1714 print(
'???', end=
'')
1715 print(
'ok'); sys.stdout.flush()
1718 print(
'make_egalwidth()...', end=
''); sys.stdout.flush()
1727 assert s == [
'(%)'], s
1728 s = [
'(%%)',
'',
'(%)']
1730 assert s == [
'(%%)',
' ',
'(%) '], s
1731 s = [
'',
'()',
'',
'(%)']
1733 assert s == [
' ',
'() ',
' ',
'(%)'], s
1734 s = [
'',
'()',
'',
'(%)']
1736 assert s == [
'///',
'()/',
'///',
'(%)'], s
1737 print(
'ok'); sys.stdout.flush()
1740 print(
'mirror()...', end=
''); sys.stdout.flush()
1745 assert mirror([
'/^^',
')']) == [
'/^^',
')'],
mirror([
'/^^',
')'])
1747 assert mirror([
'(',
'%',
')']) == [
'(',
'&',
')'],
mirror([
'(',
'%',
')'])
1748 for nb
in PRIMEKNOTS:
1749 for i
in PRIMEKNOTS[nb]:
1750 assert mirror(
mirror(PRIMEKNOTS[nb][i])) == PRIMEKNOTS[nb][i], \
1755 (nb, i,
to_states(PRIMEKNOTS[nb][i], labels),
1765 print(
'ok'); sys.stdout.flush()
1768 print(
'nb_A()...', end=
''); sys.stdout.flush()
1770 assert nb_A([CROSSUPA,
'']) == 1,
nb_A([CROSSUPA,
''])
1771 assert nb_A([CROSSDOWNA,
'']) == 1,
nb_A([c, CROSSDOWNA])
1772 for c
in LABELSTATECHARS.replace(CROSSUPA, EMPTY).replace(CROSSDOWNA, EMPTY):
1773 assert nb_A([c,
'']) == 0, (c,
nb_A([c,
'']))
1774 for nb
in PRIMEKNOTS:
1775 for i
in PRIMEKNOTS[nb]:
1778 (nb, i, PRIMEKNOTS[nb][i],
1780 labels.count(
'A'), labels,
to_labelstates(PRIMEKNOTS[nb][i], labels))
1784 (nb, i, PRIMEKNOTS[nb][i],
1789 print(
'ok'); sys.stdout.flush()
1792 print(
'nb_B()...', end=
''); sys.stdout.flush()
1794 assert nb_B([CROSSUPB,
'']) == 1,
nb_B([CROSSUPB,
''])
1795 assert nb_B([CROSSDOWNB,
'']) == 1,
nb_B([CROSSDOWNB,
''])
1796 for c
in LABELSTATECHARS.replace(CROSSUPB, EMPTY).replace(CROSSDOWNB, EMPTY):
1797 assert nb_B([c,
'']) == 0, (c,
nb_B([c,
'']))
1798 for nb
in PRIMEKNOTS:
1799 for i
in PRIMEKNOTS[nb]:
1802 (nb, i, PRIMEKNOTS[nb][i],
1804 labels.count(
'B'), labels,
to_labelstates(PRIMEKNOTS[nb][i], labels))
1808 (nb, i, PRIMEKNOTS[nb][i],
1813 print(
'ok'); sys.stdout.flush()
1816 print(
'nb_cross()...', end=
''); sys.stdout.flush()
1827 for c
in KNOTCHARS.replace(CROSSUP, EMPTY).replace(CROSSDOWN, EMPTY):
1829 for nb
in PRIMEKNOTS:
1830 for i
in PRIMEKNOTS[nb]:
1831 assert nb_cross(PRIMEKNOTS[nb][i]) == nb, \
1832 (nb, i,
nb_cross(PRIMEKNOTS[nb][i]), PRIMEKNOTS[nb][i])
1833 assert nb_cross(PRIMEKNOTS[nb][i]) \
1834 ==
nb_items(PRIMEKNOTS[nb][i], CROSSUP) \
1835 +
nb_items(PRIMEKNOTS[nb][i], CROSSDOWN), \
1836 (nb, i,
nb_cross(PRIMEKNOTS[nb][i]),
1837 nb_items(PRIMEKNOTS[nb][i], CROSSUP),
1838 nb_items(PRIMEKNOTS[nb][i], CROSSDOWN),
1851 print(
'ok'); sys.stdout.flush()
1854 print(
'nb_cycle()...', end=
''); sys.stdout.flush()
1861 ' ^']) == (1, 0),
nb_cycle([
' _',
'( )',
' ^'])
1864 '_']) == (0, 2),
nb_cycle([
'_',
' )',
'_'])
1867 ' _']) == (0, 2),
nb_cycle([
' _',
'( )',
' _'])
1870 ' _ ^']) == (1, 2),
nb_cycle([
' _ _',
'( )( )',
' _ ^'])
1873 '() _ ^ ^']) == (3, 2), \
1874 nb_cycle([
' _ _ _',
' ( )( )%',
'() _ ^ ^'])
1875 for c
in KNOTCHARS.replace(VERT,
1876 EMPTY).replace(HORI,
1877 EMPTY).replace(CROSSUP,
1878 EMPTY).replace(CROSSDOWN, EMPTY):
1883 for c
in VERT + HORI + CROSSUP + CROSSDOWN + CROSSUPA + CROSSUPB + CROSSDOWNA + CROSSDOWNB:
1885 for nb
in PRIMEKNOTS:
1886 for i
in PRIMEKNOTS[nb]:
1887 assert nb_cycle(PRIMEKNOTS[nb][i]) == (1, 0), \
1888 (nb, i,
nb_cycle(PRIMEKNOTS[nb][i]), PRIMEKNOTS[nb][i])
1892 print(
'ok'); sys.stdout.flush()
1895 print(
'nb_items()...', end=
''); sys.stdout.flush()
1898 for c
in SPACECHARS:
1900 for nb
in PRIMEKNOTS:
1901 for i
in PRIMEKNOTS[nb]:
1902 assert nb_items(PRIMEKNOTS[nb][i],
'') == 0, \
1903 (nb, i,
nb_items(PRIMEKNOTS[nb][i],
''), PRIMEKNOTS[nb][i])
1904 assert nb_items(PRIMEKNOTS[nb][i], CROSSUP + CROSSDOWN) == nb, \
1905 (nb, i,
nb_items(PRIMEKNOTS[nb][i], CROSSUP + CROSSDOWN), PRIMEKNOTS[nb][i])
1908 CROSSUPA + CROSSDOWNA) == labels.count(
'A'), \
1909 (nb, i, PRIMEKNOTS[nb][i],
1911 CROSSUPA + CROSSDOWNA),
1912 labels.count(
'A'), labels,
to_labelstates(PRIMEKNOTS[nb][i], labels))
1914 CROSSUPB + CROSSDOWNB) == labels.count(
'B'), \
1915 (nb, i, PRIMEKNOTS[nb][i],
1917 CROSSUPB + CROSSDOWNB),
1918 labels.count(
'B'), labels,
to_labelstates(PRIMEKNOTS[nb][i], labels))
1923 (nb, i, PRIMEKNOTS[nb][i],
1926 print(
'ok'); sys.stdout.flush()
1929 print(
'poly_Kauffman()...', end=
''); sys.stdout.flush()
1944 assert p.eval((-1)) == 1, p.eval((-1))
1969 assert p.eval((-1)) == 1, p.eval((-1))
1977 assert p.eval((-1)) == 1, p.eval((-1))
1979 for nb
in PRIMEKNOTS:
1980 for i
in PRIMEKNOTS[nb]:
1995 assert p.eval((-1)) == -2, p.eval((-1))
2004 assert p.eval((-1)) == -2, p.eval((-1))
2026 for k
in range(1, 10
if debug.assertspeed >= debug.ASSERT_NORMAL
else 5):
2030 ' ']*k).eval(-1) == (-2)**(k - 1), \
2032 assert poly_Kauffman([
'(%)'*k]).eval(-1) == (-2)**(k - 1), \
2034 if debug.assertspeed < debug.ASSERT_NORMAL:
2035 print(debug.assertspeed_str(), end=
'')
2036 print(
'ok'); sys.stdout.flush()
2039 print(
'poly_Kauffman_A()...', end=
''); sys.stdout.flush()
2047 assert p.eval((-1)) == 1, p.eval((-1))
2053 assert p.eval((-1)) == 1, p.eval((-1))
2068 assert p.eval((-1)) == 1, p.eval((-1))
2076 assert p.eval((-1)) == 1, p.eval((-1))
2078 for nb
in PRIMEKNOTS:
2079 for i
in PRIMEKNOTS[nb]:
2090 assert p.eval((-1)) == -2, p.eval((-1))
2097 assert p.eval((-1)) == -2, p.eval((-1))
2113 for k
in range(1, 10):
2117 ' ']*k).eval(-1) == (-2)**(k - 1), \
2119 print(
'ok'); sys.stdout.flush()
2122 print(
'poly_Kauffman_ABd()...', end=
''); sys.stdout.flush()
2125 assert p.eval((-1, -1, -2)) == -.5, p.eval((-1, -1, -2))
2132 assert p.eval((-1, -1, -2)) == 1, p.eval((-1, -1, -2))
2139 assert p.eval((-1, -1, -2)) == 1, p.eval((-1, -1, -2))
2155 assert p.eval((-1, -1, -2)) == 1, p.eval((-1, -1, -2))
2164 assert p.eval((-1, -1, -2)) == 1, p.eval((-1, -1, -2))
2166 for nb
in PRIMEKNOTS:
2167 for i
in PRIMEKNOTS[nb]:
2179 assert p.eval((-1, -1, -2)) == -2, p.eval((-1, -1, -2))
2187 assert p.eval((-1, -1, -2)) == -2, p.eval((-1, -1, -2))
2190 for k
in range(1, 10):
2195 assert p.eval((-1, -1, -2)) == (-2)**(k - 1), (k, p.eval((-1, -1, -2), (-2)**(k - 1)))
2196 print(
'ok'); sys.stdout.flush()
2199 print(
'primeknots_even_1()...', end=
''); sys.stdout.flush()
2202 for n
in range(4, 50, 2):
2207 print(
'???', end=
'')
2208 print(
'ok'); sys.stdout.flush()
2211 print(
'read()...', end=
''); sys.stdout.flush()
2212 for nb
in PRIMEKNOTS:
2213 for i
in PRIMEKNOTS[nb]:
2214 f = tempfile.NamedTemporaryFile(mode=
'w', suffix=
'.txt',
2215 prefix=
'DSPython_test_read_knots_{0}_{1}__'
2218 write(f, PRIMEKNOTS[nb][i])
2225 assert s == PRIMEKNOTS[nb][i], (nb, i, PRIMEKNOTS[nb][i], s)
2226 print(
'ok'); sys.stdout.flush()
2229 print(
'rotate()...', end=
''); sys.stdout.flush()
2235 assert rotate([
'/^^',
')']) == [
') ',
') ',
'\\_'],
rotate([
'/^^',
')'])
2236 assert rotate([
'/^^',
'',
')']) == [
') ',
') ',
'\\ _'],
rotate([
'/^^',
'',
')'])
2237 assert rotate([
'/^^',
')'], 2) == [
' (',
'__/'],
rotate([
'/^^',
')'], 2)
2238 assert rotate([
'/^^',
')'], 3) == [
'^\\',
' (',
' ('],
rotate([
'/^^',
')'], 3)
2239 assert rotate([
'/^^',
')'], 4) == [
'/^^',
')'],
rotate([
'/^^',
')'], 4)
2240 assert rotate([
'/^^',
')'], -1) == [
'^\\',
' (',
' ('],
rotate([
'/^^',
')'], -1)
2241 assert rotate([
'/^^',
')'], -2) == [
' (',
'__/'],
rotate([
'/^^',
')'], -2)
2242 assert rotate([
'/^^',
')'], -3) == [
') ',
') ',
'\\_'],
rotate([
'/^^',
')'], -3)
2243 for nb
in PRIMEKNOTS:
2244 for i
in PRIMEKNOTS[nb]:
2245 assert rotate(PRIMEKNOTS[nb][i]) ==
rotate(PRIMEKNOTS[nb][i], -3), \
2246 (nb, i,
rotate(PRIMEKNOTS[nb][i]),
rotate(PRIMEKNOTS[nb][i], -3))
2247 assert rotate(PRIMEKNOTS[nb][i], 2) ==
rotate(PRIMEKNOTS[nb][i], -2), \
2248 (nb, i,
rotate(PRIMEKNOTS[nb][i], 2),
rotate(PRIMEKNOTS[nb][i], -2))
2249 assert rotate(PRIMEKNOTS[nb][i], 3) ==
rotate(PRIMEKNOTS[nb][i], -1), \
2250 (nb, i,
rotate(PRIMEKNOTS[nb][i], 3),
rotate(PRIMEKNOTS[nb][i], -1))
2251 assert rotate(PRIMEKNOTS[nb][i], 4) == PRIMEKNOTS[nb][i], \
2252 (nb, i,
rotate(PRIMEKNOTS[nb][i]), 4)
2253 assert rotate(PRIMEKNOTS[nb][i], 12) == PRIMEKNOTS[nb][i], \
2254 (nb, i,
rotate(PRIMEKNOTS[nb][i]), 12)
2255 assert rotate(PRIMEKNOTS[nb][i], -4) == PRIMEKNOTS[nb][i], \
2256 (nb, i,
rotate(PRIMEKNOTS[nb][i]), -4)
2259 s_egalwidth += PRIMEKNOTS[nb][i]
2262 s += PRIMEKNOTS[nb][i]
2264 assert s == PRIMEKNOTS[nb][i], (nb, i, s_egalwidth)
2266 assert s == PRIMEKNOTS[nb][i], (nb, i, s_egalwidth)
2268 assert s == PRIMEKNOTS[nb][i], (nb, i, s_egalwidth)
2271 assert s == s_egalwidth, (nb, i, s_egalwidth)
2273 s += PRIMEKNOTS[nb][i]
2276 assert s == s_egalwidth, (nb, i, s_egalwidth)
2278 s += PRIMEKNOTS[nb][i]
2281 t += PRIMEKNOTS[nb][i]
2283 assert s == t, (nb, i, s, t)
2285 for labels
in [
'A'*nb,
'B'*nb]:
2298 print(
'ok'); sys.stdout.flush()
2301 print(
'space_is()...', end=
''); sys.stdout.flush()
2305 assert not space_is([EMPTY, 666,
''])
2312 for c
in SPACECHARS:
2314 for i
in range(256):
2320 for nb
in PRIMEKNOTS:
2321 for i
in PRIMEKNOTS[nb]:
2322 assert space_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
2327 (nb, i,
to_states(PRIMEKNOTS[nb][i], labels))
2330 print(
'ok'); sys.stdout.flush()
2333 print(
'states_is()...', end=
''); sys.stdout.flush()
2336 for c
in STATECHARS:
2338 for i
in range(256):
2342 for nb
in PRIMEKNOTS:
2343 for i
in PRIMEKNOTS[nb]:
2346 (nb, i, PRIMEKNOTS[nb][i], labels,
to_states(PRIMEKNOTS[nb][i]))
2348 for i
in PRIMEKNOTS[nb]:
2349 assert not states_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
2352 (nb, i, PRIMEKNOTS[nb][i], labels,
2355 (nb, i, PRIMEKNOTS[nb][i],
to_universes(PRIMEKNOTS[nb][i]))
2356 print(
'ok'); sys.stdout.flush()
2359 print(
'to_labelstates()...', end=
''); sys.stdout.flush()
2365 assert to_labelstates([CROSSDOWN,
''],
'B') == [CROSSDOWNB,
''], \
2372 assert to_labelstates([CROSSDOWNA,
''],
'B') == [CROSSDOWNB,
''], \
2374 for c
in KNOTCHARS.replace(CROSSUP, EMPTY).replace(CROSSDOWN, EMPTY):
2380 assert to_labelstates(PRIMEKNOTS[3][1]) == [
' /A\\',
'(( a',
' \\A/'], \
2382 assert to_labelstates(PRIMEKNOTS[3][1],
'B') == [
' /B\\',
'(( a',
' \\A/'], \
2384 assert to_labelstates(PRIMEKNOTS[3][1],
'AAA') == [
' /A\\',
'(( a',
' \\A/'], \
2386 assert to_labelstates(PRIMEKNOTS[3][1],
'AAB') == [
' /A\\',
'(( a',
' \\B/'], \
2388 assert to_labelstates(PRIMEKNOTS[3][1],
'ABA') == [
' /A\\',
'(( b',
' \\A/'], \
2390 assert to_labelstates(PRIMEKNOTS[3][1],
'ABB') == [
' /A\\',
'(( b',
' \\B/'], \
2392 assert to_labelstates(PRIMEKNOTS[3][1],
'BAA') == [
' /B\\',
'(( a',
' \\A/'], \
2394 assert to_labelstates(PRIMEKNOTS[3][1],
'BAB') == [
' /B\\',
'(( a',
' \\B/'], \
2396 assert to_labelstates(PRIMEKNOTS[3][1],
'BBA') == [
' /B\\',
'(( b',
' \\A/'], \
2398 assert to_labelstates(PRIMEKNOTS[3][1],
'BBB') == [
' /B\\',
'(( b',
' \\B/'], \
2401 == [
' _____',
'/ \\',
'AAAAAAA',
'\\ /',
' ^^^^^'], \
2405 == [
' _____',
'/ \\', labels,
'\\ /',
' ^^^^^'], \
2407 for nb
in PRIMEKNOTS:
2408 for i
in PRIMEKNOTS[nb]:
2420 print(
'ok'); sys.stdout.flush()
2423 print(
'to_LaTeX()...', end=
''); sys.stdout.flush()
2424 assert isinstance(
to_LaTeX([]), str)
2425 assert isinstance(
to_LaTeX([
'']), str)
2426 assert isinstance(
to_LaTeX([]), str)
2427 for nb
in PRIMEKNOTS:
2428 for i
in PRIMEKNOTS[nb]:
2429 assert isinstance(
to_LaTeX(PRIMEKNOTS[nb][i]), str), (nb, i)
2430 assert isinstance(
to_LaTeX(PRIMEKNOTS[nb][i],
2431 length=20, shape=5, grid=
True), str), (nb, i)
2432 print(
'ok'); sys.stdout.flush()
2435 print(
'to_PS()...', end=
''); sys.stdout.flush()
2436 assert isinstance(
to_PS([]), str)
2437 assert isinstance(
to_PS([
'']), str)
2438 assert isinstance(
to_PS([]), str)
2439 for nb
in PRIMEKNOTS:
2440 for i
in PRIMEKNOTS[nb]:
2441 assert isinstance(
to_PS(PRIMEKNOTS[nb][i]), str), (nb, i)
2442 assert isinstance(
to_PS(PRIMEKNOTS[nb][i],
2443 length=20, margin=0, shape=5, grid=
True), str), (nb, i)
2444 print(
'ok'); sys.stdout.flush()
2447 print(
'to_states()...', end=
''); sys.stdout.flush()
2450 assert to_states([CROSSUP,
''],
'B') == [HORI,
''], \
2453 assert to_states([CROSSDOWN,
''],
'B') == [VERT,
''], \
2456 assert to_states([CROSSUPA,
''],
'B') == [HORI,
''], \
2459 assert to_states([CROSSDOWNA,
''],
'B') == [VERT,
''], \
2461 for c
in (KNOTCHARS + VERT + HORI) \
2462 .replace(CROSSUP, EMPTY).replace(CROSSDOWN, EMPTY):
2464 assert to_states([c,
''], labels) == [c,
''], \
2467 assert to_states(PRIMEKNOTS[3][1]) == [
' /"\\',
'(( =',
' \\"/'], \
2469 assert to_states(PRIMEKNOTS[3][1],
'B') == [
' /=\\',
'(( =',
' \\"/'], \
2471 assert to_states(PRIMEKNOTS[3][1],
'AAA') == [
' /"\\',
'(( =',
' \\"/'], \
2473 assert to_states(PRIMEKNOTS[3][1],
'AAB') == [
' /"\\',
'(( =',
' \\=/'], \
2475 assert to_states(PRIMEKNOTS[3][1],
'ABA') == [
' /"\\',
'(( "',
' \\"/'], \
2477 assert to_states(PRIMEKNOTS[3][1],
'ABB') == [
' /"\\',
'(( "',
' \\=/'], \
2479 assert to_states(PRIMEKNOTS[3][1],
'BAA') == [
' /=\\',
'(( =',
' \\"/'], \
2481 assert to_states(PRIMEKNOTS[3][1],
'BAB') == [
' /=\\',
'(( =',
' \\=/'], \
2483 assert to_states(PRIMEKNOTS[3][1],
'BBA') == [
' /=\\',
'(( "',
' \\"/'], \
2485 assert to_states(PRIMEKNOTS[3][1],
'BBB') == [
' /=\\',
'(( "',
' \\=/'], \
2488 == [
' _____',
'/ \\',
'"""""""',
'\\ /',
' ^^^^^'], \
2491 assert to_states(PRIMEKNOTS[7][1], labels) \
2492 == [
' _____',
'/ \\', labels.replace(
'A',
'"').replace(
'B',
'='),
2493 '\\ /',
' ^^^^^'], (labels,
to_states(PRIMEKNOTS[7][1]))
2494 for nb
in PRIMEKNOTS:
2495 for i
in PRIMEKNOTS[nb]:
2497 s =
to_states(PRIMEKNOTS[nb][i], labels)
2498 assert states_is(s), (nb, i, labels, PRIMEKNOTS[nb][i], s)
2511 print(
'ok'); sys.stdout.flush()
2514 print(
'to_str()...', end=
''); sys.stdout.flush()
2516 for c
in SPACECHARS:
2517 assert to_str([c,
'']) == c +
'\n', (c,
to_str([c,
'']))
2518 assert to_str([c, c]) == c +
'\n' + c, (c,
to_str([c, c]))
2519 assert to_str(PRIMEKNOTS[0][1]) ==
'()',
to_str(PRIMEKNOTS[0][1])
2520 assert to_str(PRIMEKNOTS[7][1]) ==
' _____\n/ \\\n%%%%%%%\n\\ /\n ^^^^^', \
2524 ==
' _____\n/ \\\n{0}\n\\ /\n ^^^^^'.format(labels), \
2527 ==
' _____\n/ \\\n{0}\n\\ /\n ^^^^^' \
2528 .format(labels.replace(
'A',
'"').replace(
'B',
'=')), \
2531 ==
' _____\n/ \\\nxxxxxxx\n\\ /\n ^^^^^', \
2533 print(
'ok'); sys.stdout.flush()
2536 print(
'to_universes()...', end=
''); sys.stdout.flush()
2538 for c
in KNOTCHARS.replace(CROSSUP, EMPTY).replace(CROSSDOWN, EMPTY):
2547 assert to_universes(PRIMEKNOTS[3][1]) == [
' /x\\',
'(( x',
' \\x/'], \
2550 == [
' _____',
'/ \\',
'xxxxxxx',
'\\ /',
' ^^^^^'], \
2552 for nb
in PRIMEKNOTS:
2553 for i
in PRIMEKNOTS[nb]:
2569 print(
'ok'); sys.stdout.flush()
2572 print(
'universes_is()...', end=
''); sys.stdout.flush()
2575 for c
in UNIVERSECHARS:
2577 for i
in range(256):
2579 if c
in UNIVERSECHARS:
2581 for nb
in PRIMEKNOTS:
2582 for i
in PRIMEKNOTS[nb]:
2584 (nb, i, PRIMEKNOTS[nb][i],
to_universes(PRIMEKNOTS[nb][i]))
2586 for i
in PRIMEKNOTS[nb]:
2589 (nb, i, PRIMEKNOTS[nb][i], labels,
2592 (nb, i, PRIMEKNOTS[nb][i], labels,
2594 assert not universes_is(PRIMEKNOTS[nb][i]), (nb, i, PRIMEKNOTS[nb][i])
2595 print(
'ok'); sys.stdout.flush()
2598 print(
'write()...', end=
''); sys.stdout.flush()
2600 f = tempfile.NamedTemporaryFile(mode=
'w', suffix=
'.txt',
2601 prefix=
'DSPython_test_write_knots_{0}_{1}__'.format(nb, i),
2603 for nb
in PRIMEKNOTS:
2604 for i
in PRIMEKNOTS[nb]:
2605 write(f, PRIMEKNOTS[nb][i])
2606 s += PRIMEKNOTS[nb][i]
2613 assert r == s, (r, s)
2614 print(
'ok'); sys.stdout.flush()
2617 print(
'writhe()...', end=
''); sys.stdout.flush()
2622 for nb
in PRIMEKNOTS:
2623 for i
in PRIMEKNOTS[nb]:
2624 assert -nb <=
writhe(PRIMEKNOTS[nb][i]) <= nb, (nb, i,
writhe(PRIMEKNOTS[nb][i]))
2627 print(
'???', end=
'')
2628 print(
'ok'); sys.stdout.flush()
2631 print(
'writhe_cross()...', end=
''); sys.stdout.flush()
2645 assert writhe_cross(s, 1, 0) == 0, a.writhe_cross(s, 1, 0)
2646 assert writhe_cross(s, 0, 1) == 0, a.writhe_cross(s, 0, 1)
2650 assert writhe_cross(s, 1, 0) == 0, a.writhe_cross(s, 1, 0)
2651 assert writhe_cross(s, 0, 1) == 0, a.writhe_cross(s, 0, 1)
2660 print(
'ok'); sys.stdout.flush()
2664 print(
'Corners()...', end=
''); sys.stdout.flush()
2665 print(
'???', end=
'')
2666 print(
'ok'); sys.stdout.flush()
2669 print(
'Corners.extremity()...', end=
''); sys.stdout.flush()
2670 print(
'???', end=
'')
2671 print(
'ok'); sys.stdout.flush()
2674 print(
'Corners.nb_cycle()...', end=
''); sys.stdout.flush()
2694 '() _ ^ ^']).
nb_cycle() == (3, 2), \
2696 for c
in KNOTCHARS.replace(VERT, EMPTY).replace(HORI, EMPTY) \
2697 .replace(CROSSUP, EMPTY).replace(CROSSDOWN, EMPTY):
2702 for c
in VERT + HORI + CROSSUP + CROSSDOWN + CROSSUPA + CROSSUPB + CROSSDOWNA + CROSSDOWNB:
2704 for nb
in PRIMEKNOTS:
2705 for i
in PRIMEKNOTS[nb]:
2711 print(
'ok'); sys.stdout.flush()
2714 print(
'Corners.writhe_cross()...', end=
''); sys.stdout.flush()
2716 assert a.writhe_cross(1, 0,
True) == 1, a.writhe_cross(1, 0,
True)
2717 assert a.writhe_cross(1, 0,
False) == -1, a.writhe_cross(1, 0,
False)
2721 assert a.writhe_cross(0, 1,
True) == -1, a.writhe_cross(0, 1,
True)
2722 assert a.writhe_cross(0, 1,
False) == 1, a.writhe_cross(0, 1,
False)
2726 assert a.writhe_cross(1, 0,
True) == 0, a.writhe_cross(1, 0,
True)
2727 assert a.writhe_cross(1, 0,
False) == 0, a.writhe_cross(1, 0,
False)
2728 assert a.writhe_cross(0, 1,
True) == 0, a.writhe_cross(0, 1,
True)
2729 assert a.writhe_cross(0, 1,
False) == 0, a.writhe_cross(0, 1,
False)
2733 assert a.writhe_cross(1, 0,
True) == 0, a.writhe_cross(1, 0,
True)
2734 assert a.writhe_cross(1, 0,
False) == 0, a.writhe_cross(1, 0,
False)
2735 assert a.writhe_cross(0, 1,
True) == 0, a.writhe_cross(0, 1,
True)
2736 assert a.writhe_cross(0, 1,
False) == 0, a.writhe_cross(0, 1,
False)
2740 assert a.writhe_cross(1, 0,
True) == -1, a.writhe_cross(1, 0,
True)
2741 assert a.writhe_cross(1, 0,
False) == 1, a.writhe_cross(1, 0,
False)
2742 print(
'ok'); sys.stdout.flush()