Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
added graphical tables + pep8 formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoStint committed Oct 27, 2022
1 parent 6d31aad commit e63fa09
Showing 1 changed file with 75 additions and 33 deletions.
108 changes: 75 additions & 33 deletions src/sage/matrix/operation_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ class OperationTable(SageObject):
- Rob Beezer (2010-03-15)
"""

def __init__(self, S, operation, names='letters', elements=None):
r"""
TESTS::
Expand All @@ -397,7 +398,7 @@ def __init__(self, S, operation, names='letters', elements=None):
# Note: there exist listable infinite objects (like ZZ)
if (elements is None):
if hasattr(S, 'is_finite'):
if not(S.is_finite()):
if not (S.is_finite()):
raise ValueError('%s is infinite' % S)
try:
try:
Expand All @@ -411,7 +412,7 @@ def __init__(self, S, operation, names='letters', elements=None):
try:
for e in elements:
coerced = S(e)
if not(coerced in elems):
if not (coerced in elems):
elems.append(coerced)
except Exception:
raise TypeError('unable to coerce %s into %s' % (e, S))
Expand All @@ -432,7 +433,7 @@ def __init__(self, S, operation, names='letters', elements=None):
supported = {
add: (add, '+', '+'),
mul: (mul, '*', '\\ast')
}
}
# default symbols for upper-left-hand-corner of table
self._ascii_symbol = '.'
self._latex_symbol = '\\cdot'
Expand All @@ -451,7 +452,7 @@ def __init__(self, S, operation, names='letters', elements=None):
# the elements might not be hashable. But if they are it is much
# faster to lookup in a hash table rather than in a list!
try:
get_row = {e: i for i,e in enumerate(self._elts)}.__getitem__
get_row = {e: i for i, e in enumerate(self._elts)}.__getitem__
except TypeError:
get_row = self._elts.index

Expand All @@ -461,7 +462,8 @@ def __init__(self, S, operation, names='letters', elements=None):
try:
result = self._operation(g, h)
except Exception:
raise TypeError('elements %s and %s of %s are incompatible with operation: %s' % (g,h,S,self._operation))
raise TypeError('elements %s and %s of %s are incompatible with operation: %s' % (
g, h, S, self._operation))

try:
r = get_row(result)
Expand All @@ -477,7 +479,8 @@ def __init__(self, S, operation, names='letters', elements=None):
except (KeyError, ValueError):
failed = True
if failed:
raise ValueError('%s%s%s=%s, and so the set is not closed' % (g, self._ascii_symbol, h, result))
raise ValueError('%s%s%s=%s, and so the set is not closed' % (
g, self._ascii_symbol, h, result))

row.append(r)
self._table.append(row)
Expand Down Expand Up @@ -558,7 +561,8 @@ def _name_maker(self, names):
else:
width = int(log(self._n - 1, base)) + 1
for i in range(self._n):
places = Integer(i).digits(base=base, digits=letters, padto=width)
places = Integer(i).digits(
base=base, digits=letters, padto=width)
places.reverse()
name_list.append(''.join(places))
elif names == 'elements':
Expand All @@ -570,19 +574,22 @@ def _name_maker(self, names):
name_list.append(estr)
elif isinstance(names, list):
if len(names) != self._n:
raise ValueError('list of element names must be the same size as the set, %s != %s'%(len(names), self._n))
raise ValueError('list of element names must be the same size as the set, %s != %s' % (
len(names), self._n))
width = 0
for name in names:
if not isinstance(name, str):
raise ValueError('list of element names must only contain strings, not %s' % name)
raise ValueError(
'list of element names must only contain strings, not %s' % name)
if len(name) > width:
width = len(name)
name_list.append(name)
else:
raise ValueError("element names must be a list, or one of the keywords: 'letters', 'digits', 'elements'")
raise ValueError(
"element names must be a list, or one of the keywords: 'letters', 'digits', 'elements'")
name_dict = {}
for i in range(self._n):
name_dict[name_list[i]]=self._elts[i]
name_dict[name_list[i]] = self._elts[i]
return width, name_list, name_dict

def __getitem__(self, pair):
Expand Down Expand Up @@ -632,13 +639,15 @@ def __getitem__(self, pair):
IndexError: invalid indices of operation table: ((1,512), (1,3,2,4)(5,7))
"""
if not (isinstance(pair, tuple) and len(pair) == 2):
raise TypeError('indexing into an operation table requires exactly two elements')
raise TypeError(
'indexing into an operation table requires exactly two elements')
g, h = pair
try:
row = self._elts.index(g)
col = self._elts.index(h)
except ValueError:
raise IndexError('invalid indices of operation table: (%s, %s)' % (g, h))
raise IndexError(
'invalid indices of operation table: (%s, %s)' % (g, h))
return self._elts[self._table[row][col]]

def __eq__(self, other):
Expand Down Expand Up @@ -747,8 +756,9 @@ def set_print_symbols(self, ascii, latex):
...
ValueError: ASCII symbol should be a single character, not 5
"""
if not isinstance(ascii, str) or not len(ascii)==1:
raise ValueError('ASCII symbol should be a single character, not %s' % ascii)
if not isinstance(ascii, str) or not len(ascii) == 1:
raise ValueError(
'ASCII symbol should be a single character, not %s' % ascii)
if not isinstance(latex, str):
raise ValueError('LaTeX symbol must be a string, not %s' % latex)
self._ascii_symbol = ascii
Expand Down Expand Up @@ -935,22 +945,53 @@ def matrix_of_variables(self):
from sage.rings.rational_field import QQ
R = PolynomialRing(QQ, 'x', self._n)
MS = MatrixSpace(R, self._n, self._n)
entries = [R('x'+str(self._table[i][j])) for i in range(self._n) for j in range(self._n)]
return MS( entries )

#def color_table():
#r"""
#Returns a graphic image as a square grid where entries are color coded.
#"""
#pass
#return None

#def gray_table():
#r"""
#Returns a graphic image as a square grid where entries are coded as grayscale values.
#"""
#pass
#return None
entries = [R('x'+str(self._table[i][j]))
for i in range(self._n) for j in range(self._n)]
return MS(entries)

def color_table(self, element_names=True, cmap=gist_rainbow, **options):
r"""
Returns a graphic image as a square grid where entries are color coded.
INPUT:
- ``element_names`` - (default : ``True``) Whether to display text with element names on the image
- ``cmap`` - (default : ``gist_rainbow``) colour map for plot, see matplotlib.cm
- ``**options`` - passed on to matrix_plot call
"""

# Base matrix plot object, without text
plot = matrix_plot(Matrix(self._table), cmap=cmap,
frame=False, **options)

if element_names:

# adapted from ._ascii_table()
# prepare widenames[] list for labelling on image
n = self._n
width = self._width

widenames = []
for name in self._names:
widenames.append("{0: >{1}s}".format(name, width))

# iterate through each element
for g in range(n):
for h in range(n):

# add text to the plot
tPos = (g, h)
tText = widenames[self._table[g][h]]
t = text(tText, tPos, rgbcolor=(0, 0, 0))
plot = plot + t

return plot

def gray_table(self, **options):
return self.color_table(cmap=Greys, **options)

def _ascii_table(self):
r"""
Expand Down Expand Up @@ -1031,7 +1072,7 @@ def _ascii_table(self):
widenames.append('{0: >{1}s}'.format(name, width))

# Headers
table = ['{0: >{1}s} '.format(self._ascii_symbol,width)]
table = ['{0: >{1}s} '.format(self._ascii_symbol, width)]
table += [' '+widenames[i] for i in range(n)]+['\n']
table += [' ']*width + ['+'] + ['-']*(n*(width+1))+['\n']

Expand Down Expand Up @@ -1068,7 +1109,8 @@ def _latex_(self):

# Row label and body of table
for g in range(n):
table.append('{}') # Interrupts newline and [], so not line spacing
# Interrupts newline and [], so not line spacing
table.append('{}')
table.append(names[g])
for h in range(n):
table.append('&'+names[self._table[g][h]])
Expand Down

0 comments on commit e63fa09

Please sign in to comment.