Python algorithm that converts array-like data into MathJax I frequently use MathJax, and often I need to write matrices. Since writing matrices using MathJax is very tiresome task, I decided to automate it.

Code:

import numpy as np
import pyperclip


class Conversion():


    def __init__(self, matrix, n = None, m = None):
        if matrix == None:
            self.matrix = np.random.randint(-10,10, size = [n,m])
        else:
            '''If variable "matrix", for example, contains [1,2,3,4], instead of [[1,2,3,4]], functions below 
            will throw error, hence we need to make sure that the data type is correct.'''
            if type(matrix[0]) in (str,int,float):
                self.matrix = np.array([matrix,])
            else:
                self.matrix = np.array(matrix)

        self.rows = len(self.matrix)
        self.cols = len(self.matrix[0])


    def single(self, choosen_brackets = ')'):
        available_brackets = {' ' : 'matrix', 
                              ')' : 'pmatrix', 
                              ']' : 'bmatrix', 
                              '}' : 'Bmatrix', 
                              '|' : 'vmatrix',
                              '||': 'Vmatrix'  }
        choosen_brackets = available_brackets[choosen_brackets]
        body = '$$\\begin {} \n'.format('{' + choosen_brackets + '}')
        for row in self.matrix: 
            row = [str(x) for x in row]
            body += ' &amp; '.join(row) + '\\\\' + '\n'
        body +='\end {} $$'.format('{' + choosen_brackets + '}')
        print(body)
        pyperclip.copy(body)


    def augmented(self, choosen_brackets = '[]'):
        '''We are assuming that the last column of the given matrix is a vector.'''

        pos_of_the_verticar_bar = '{' + 'c'*(self.cols-1) + '|' + 'c' + '}'
        body = '$$\\left [ \\begin {array} %s \n' % (pos_of_the_verticar_bar)
        for row in self.matrix:
            row = [str(x) for x in row]
            body += ' &amp; '.join(row) + '\\\\' + '\n'
        body +='\end {array} \\right ]$$'
        print(body)
        pyperclip.copy(body)


Notes:


Since function augmented is quite similar to single, I could've merged  them into one. However, I think that keeping them separate makes the code a little bit more readable.
On MSE, mathjax equations are enclosed with $$ instead of \$
"single" is a bad name for a function, I admit. I haven't found any better options. Feel free to offer suggestions.


What can be improved?

Written for Python 3.6.5.
This looks like a handy tool to have around, maybe we can make it even better.

Style

As per the official Python Style Guide (often known by his nickname PEP8), keyword-arguments of functions should have no whitespace around the =.

Matrix size

numpy arrays have a property called .shape which describes their number of rows and number of cols (in case of a 2D array at least). So

self.rows = len(self.matrix)
self.cols = len(self.matrix[0])


could become

self.rows, self.cols = self.matrix.shape


Since your code only works for 2D matrices, it's maybe also a good idea to check for that. The .ndim attribute can be of help here.

Type checking

type(matrix[0]) in (str,int,float) should instead be isinstance(matrix[0], (str, int, float)).

Checking None

The official recommendation is to always use if sth is None: when checking for None.

String joining


row = [str(x) for x in row]
body += ' &amp; '.join(row) + '\\\\' + '\n'



could be done in a single line:

body += ' &amp; '.join(str(x) for x in row) + '\\\\' + '\n'


This means you also don't have to reassign row to be something different than it was before.

String formatting

Since you said you're using Python 3.6, maybe have a look at f-strings for even more concise string formatting syntax. No matter if you choose to do this, maybe at least get rid of the old-style % formatting in augmented(...) by escaping { and } using a leading \.

Function output

I find it preferable if you'd let the user decide what he wants to do with what your function returns. So instead of printing and copying the formatted matrix code, maybe just return body and let the caller decide how to proceed from here. You could even define a "convenience" function (to_clipboard) that basically only does pyperclip.copy(...), although this is likely not necessary. Another idea would be to make at least the copy part opt-in via a "flag" bool parameter.

Class

Maybe a class is not the right tool here. A possible alternative would be to move what's done in __init__ into a "private" (read name starts with _) helper function and get rid of the class.



Missing backslash

There seems to be a little bug in both of your functions (see how bad code duplication is ;-)): body +='\end ... is likely missing an additional \.

Unused argument

If I'm not mistaken, the choosen_brackets argument of augmented is not used in the function.

Typo

choosen_brackets should likely be chosen_brackets