Python algorithm that converts array-like data into MathJaxInserting data into database by PythonPython data massagerPython script converts after effects clipboard keyframe data to nuke keyframe dataTetris-like algorithm (2D matrix)Python Script: Converts .tsv to TFRecordSort array into wave like arrayStroke Algorithm in pythonReading serial data from Arduino into Python every 100 msEffective fetching data algorithmAlgorithm that spans orthogonal vectors: Python

Will you be able to hear a supersonic aircraft flying away from you?

What are these tiny kidney bean sized things in my rotisserie chicken

Did any astronauts on a mission complain about waking up?

copying files with a string in their name from one folder to another

20 cards with no Set

Is there a benefit to leaving reviews on Expedia?

Is camera at risk of condensation in cold temperatures if never removed from bag?

What would cause vast differences in lifespans between the sexes?

Are the expansion number tokens in 5-6 players expansion different from the basic Catan?

Variable in SOSL Query

Affrication-like sound in palatal plosive [c]

What is the purpose of R1 in this circuit?

What does Darth Vader think Obi-Wan's referring to when Obi says "If you strike me down..."

How to quantify Code Quality

How to use rules — did this change between editions and how?

Christmas party and autism

Doing chemistry under water?

PyQGIS using selected layer from a combobox

Paint Exterior Door that is in Sun

Mordhau grip for bludgeoning damage?

How do people create difficult, recreational problems (e.g. like those found in competitions such as the IMO)?

Why do airline tickets have titles in addition to names?

Why would a life company agree to a 20-year guaranteed life annuity which is expected to pay out more than the principal?

Why is the Exchange French considered drawish?



Python algorithm that converts array-like data into MathJax


Inserting data into database by PythonPython data massagerPython script converts after effects clipboard keyframe data to nuke keyframe dataTetris-like algorithm (2D matrix)Python Script: Converts .tsv to TFRecordSort array into wave like arrayStroke Algorithm in pythonReading serial data from Arduino into Python every 100 msEffective fetching data algorithmAlgorithm that spans orthogonal vectors: Python






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









12














$begingroup$


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 += ' & '.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) + ''
body = '$$\left [ \begin array %s n' % (pos_of_the_verticar_bar)
for row in self.matrix:
row = [str(x) for x in row]
body += ' & '.join(row) + '\\' + 'n'
body +='end array \right ]$$
'
print(body)
pyperclip.copy(body)


Notes:



  1. 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.


  2. On MSE, mathjax equations are enclosed with $$ instead of $


  3. "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.










share|improve this question












$endgroup$





















    12














    $begingroup$


    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 += ' & '.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) + ''
    body = '$$\left [ \begin array %s n' % (pos_of_the_verticar_bar)
    for row in self.matrix:
    row = [str(x) for x in row]
    body += ' & '.join(row) + '\\' + 'n'
    body +='end array \right ]$$
    '
    print(body)
    pyperclip.copy(body)


    Notes:



    1. 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.


    2. On MSE, mathjax equations are enclosed with $$ instead of $


    3. "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.










    share|improve this question












    $endgroup$

















      12












      12








      12


      2



      $begingroup$


      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 += ' & '.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) + ''
      body = '$$\left [ \begin array %s n' % (pos_of_the_verticar_bar)
      for row in self.matrix:
      row = [str(x) for x in row]
      body += ' & '.join(row) + '\\' + 'n'
      body +='end array \right ]$$
      '
      print(body)
      pyperclip.copy(body)


      Notes:



      1. 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.


      2. On MSE, mathjax equations are enclosed with $$ instead of $


      3. "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.










      share|improve this question












      $endgroup$




      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 += ' & '.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) + ''
      body = '$$\left [ \begin array %s n' % (pos_of_the_verticar_bar)
      for row in self.matrix:
      row = [str(x) for x in row]
      body += ' & '.join(row) + '\\' + 'n'
      body +='end array \right ]$$
      '
      print(body)
      pyperclip.copy(body)


      Notes:



      1. 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.


      2. On MSE, mathjax equations are enclosed with $$ instead of $


      3. "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.







      python python-3.x matrix formatting latex






      share|improve this question
















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 16 at 3:44









      200_success

      136k21 gold badges175 silver badges448 bronze badges




      136k21 gold badges175 silver badges448 bronze badges










      asked Oct 15 at 14:46









      NelverNelver

      37512 bronze badges




      37512 bronze badges























          2 Answers
          2






          active

          oldest

          votes


















          12
















          $begingroup$

          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 += ' & '.join(row) + '\\' + 'n'



          could be done in a single line:



          body += ' & '.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






          share|improve this answer












          $endgroup$














          • $begingroup$
            Thank you for your review! May I ask why it is recommended to use is None instead of == None?
            $endgroup$
            – Nelver
            Oct 16 at 2:19











          • $begingroup$
            Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
            $endgroup$
            – AlexV
            Oct 16 at 7:47


















          9
















          $begingroup$

          Python's string formatting has come a long way from the "%s" formatting days. Nowadays classes can even determine on their own how to handle format specifiers. Therefore I would write a matrix class that can be pretty printed with different format options determining the matrix style.



          class MathJaxMatrix:
          brackets = '': 'matrix',
          'p': 'pmatrix',
          'b': 'bmatrix',
          'B': 'Bmatrix',
          'v': 'vmatrix',
          'V': 'Vmatrix'
          e_msg = "unsupported format string passed to MathJaxMatrix.__format__"

          def __init__(self, m):
          if m.ndim == 1:
          m = m.reshape(len(m), 1)
          self.m = m
          self.rows, self.cols = m.shape

          def __str__(self):
          return "\\ n".join(" & ".join(str(x) for x in row) for row in self.m)

          def __format__(self, format_spec=None):
          if format_spec is None:
          return str(self)
          if format_spec == "a":
          format_spec = 'c'
          start = rf'$$left[ beginarrayformat_spec'
          end = r'endarray right]$$
          '
          else:
          try:
          brackets = self.brackets[format_spec]
          except KeyError as e:
          raise TypeError(self.e_msg) from e
          start = f'$$ \beginbrackets'
          end = f'endbrackets $$
          '
          return "n".join([start, str(self), end])


          Which you can use like this:



          In [40]: x = np.random.rand(4, 5)

          In [41]: m = MathJaxMatrix(x)

          In [42]: print(m)
          0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
          0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
          0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
          0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448

          In [43]: print(f"m")
          $$beginmatrix
          0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
          0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
          0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
          0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
          endmatrix $$


          In [44]: print(f"m:p")
          $$beginpmatrix
          0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
          0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
          0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
          0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
          endpmatrix $$


          In [45]: print(f"m:a")
          $$ left[ beginarrayc
          0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
          0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
          0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
          0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
          endarray right] $$


          In [62]: print(f"m:e")
          ---------------------------------------------------------------------------
          KeyError Traceback (most recent call last)
          ...
          KeyError: 'e'

          The above exception was the direct cause of the following exception:

          TypeError Traceback (most recent call last)
          ...
          TypeError: unsupported format string passed to MathJaxMatrix.__format__


          Note that this removes the repeated code for getting a string representation of the actual matrix, uses np.ndarray.ndim and np.reshape to ensure it is a proper 2D matrix. I used the first letter of the different *matrix options to distinguish them because } is not allowed in format specifications.



          The actual convenience function is then quite short:



          def format_matrix(m, format_spec):
          m = MathJaxMatrix(m)
          s = f"m:format_spec"
          print(s)
          pyperclip.copy(s)





          share|improve this answer












          $endgroup$
















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );














            draft saved

            draft discarded
















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f230758%2fpython-algorithm-that-converts-array-like-data-into-mathjax%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown


























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            12
















            $begingroup$

            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 += ' & '.join(row) + '\\' + 'n'



            could be done in a single line:



            body += ' & '.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






            share|improve this answer












            $endgroup$














            • $begingroup$
              Thank you for your review! May I ask why it is recommended to use is None instead of == None?
              $endgroup$
              – Nelver
              Oct 16 at 2:19











            • $begingroup$
              Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
              $endgroup$
              – AlexV
              Oct 16 at 7:47















            12
















            $begingroup$

            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 += ' & '.join(row) + '\\' + 'n'



            could be done in a single line:



            body += ' & '.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






            share|improve this answer












            $endgroup$














            • $begingroup$
              Thank you for your review! May I ask why it is recommended to use is None instead of == None?
              $endgroup$
              – Nelver
              Oct 16 at 2:19











            • $begingroup$
              Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
              $endgroup$
              – AlexV
              Oct 16 at 7:47













            12














            12










            12







            $begingroup$

            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 += ' & '.join(row) + '\\' + 'n'



            could be done in a single line:



            body += ' & '.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






            share|improve this answer












            $endgroup$



            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 += ' & '.join(row) + '\\' + 'n'



            could be done in a single line:



            body += ' & '.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







            share|improve this answer















            share|improve this answer




            share|improve this answer








            edited Oct 16 at 14:51









            t2h

            32 bronze badges




            32 bronze badges










            answered Oct 15 at 16:34









            AlexVAlexV

            5,1452 gold badges12 silver badges38 bronze badges




            5,1452 gold badges12 silver badges38 bronze badges














            • $begingroup$
              Thank you for your review! May I ask why it is recommended to use is None instead of == None?
              $endgroup$
              – Nelver
              Oct 16 at 2:19











            • $begingroup$
              Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
              $endgroup$
              – AlexV
              Oct 16 at 7:47
















            • $begingroup$
              Thank you for your review! May I ask why it is recommended to use is None instead of == None?
              $endgroup$
              – Nelver
              Oct 16 at 2:19











            • $begingroup$
              Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
              $endgroup$
              – AlexV
              Oct 16 at 7:47















            $begingroup$
            Thank you for your review! May I ask why it is recommended to use is None instead of == None?
            $endgroup$
            – Nelver
            Oct 16 at 2:19





            $begingroup$
            Thank you for your review! May I ask why it is recommended to use is None instead of == None?
            $endgroup$
            – Nelver
            Oct 16 at 2:19













            $begingroup$
            Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
            $endgroup$
            – AlexV
            Oct 16 at 7:47




            $begingroup$
            Strictly speaking, is checks if both variables point to the exact same object in memory and not just that they compare equal. Since None is a singleton, this is likely the more natural operation to use. But to be honest, there are probably not a lot of (other) hard facts why you should use is None over == None. Both variants will give you the desired result here.
            $endgroup$
            – AlexV
            Oct 16 at 7:47













            9
















            $begingroup$

            Python's string formatting has come a long way from the "%s" formatting days. Nowadays classes can even determine on their own how to handle format specifiers. Therefore I would write a matrix class that can be pretty printed with different format options determining the matrix style.



            class MathJaxMatrix:
            brackets = '': 'matrix',
            'p': 'pmatrix',
            'b': 'bmatrix',
            'B': 'Bmatrix',
            'v': 'vmatrix',
            'V': 'Vmatrix'
            e_msg = "unsupported format string passed to MathJaxMatrix.__format__"

            def __init__(self, m):
            if m.ndim == 1:
            m = m.reshape(len(m), 1)
            self.m = m
            self.rows, self.cols = m.shape

            def __str__(self):
            return "\\ n".join(" & ".join(str(x) for x in row) for row in self.m)

            def __format__(self, format_spec=None):
            if format_spec is None:
            return str(self)
            if format_spec == "a":
            format_spec = 'c'
            start = rf'$$left[ beginarrayformat_spec'
            end = r'endarray right]$$
            '
            else:
            try:
            brackets = self.brackets[format_spec]
            except KeyError as e:
            raise TypeError(self.e_msg) from e
            start = f'$$ \beginbrackets'
            end = f'endbrackets $$
            '
            return "n".join([start, str(self), end])


            Which you can use like this:



            In [40]: x = np.random.rand(4, 5)

            In [41]: m = MathJaxMatrix(x)

            In [42]: print(m)
            0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
            0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
            0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
            0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448

            In [43]: print(f"m")
            $$beginmatrix
            0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
            0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
            0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
            0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
            endmatrix $$


            In [44]: print(f"m:p")
            $$beginpmatrix
            0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
            0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
            0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
            0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
            endpmatrix $$


            In [45]: print(f"m:a")
            $$ left[ beginarrayc
            0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
            0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
            0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
            0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
            endarray right] $$


            In [62]: print(f"m:e")
            ---------------------------------------------------------------------------
            KeyError Traceback (most recent call last)
            ...
            KeyError: 'e'

            The above exception was the direct cause of the following exception:

            TypeError Traceback (most recent call last)
            ...
            TypeError: unsupported format string passed to MathJaxMatrix.__format__


            Note that this removes the repeated code for getting a string representation of the actual matrix, uses np.ndarray.ndim and np.reshape to ensure it is a proper 2D matrix. I used the first letter of the different *matrix options to distinguish them because } is not allowed in format specifications.



            The actual convenience function is then quite short:



            def format_matrix(m, format_spec):
            m = MathJaxMatrix(m)
            s = f"m:format_spec"
            print(s)
            pyperclip.copy(s)





            share|improve this answer












            $endgroup$



















              9
















              $begingroup$

              Python's string formatting has come a long way from the "%s" formatting days. Nowadays classes can even determine on their own how to handle format specifiers. Therefore I would write a matrix class that can be pretty printed with different format options determining the matrix style.



              class MathJaxMatrix:
              brackets = '': 'matrix',
              'p': 'pmatrix',
              'b': 'bmatrix',
              'B': 'Bmatrix',
              'v': 'vmatrix',
              'V': 'Vmatrix'
              e_msg = "unsupported format string passed to MathJaxMatrix.__format__"

              def __init__(self, m):
              if m.ndim == 1:
              m = m.reshape(len(m), 1)
              self.m = m
              self.rows, self.cols = m.shape

              def __str__(self):
              return "\\ n".join(" & ".join(str(x) for x in row) for row in self.m)

              def __format__(self, format_spec=None):
              if format_spec is None:
              return str(self)
              if format_spec == "a":
              format_spec = 'c'
              start = rf'$$left[ beginarrayformat_spec'
              end = r'endarray right]$$
              '
              else:
              try:
              brackets = self.brackets[format_spec]
              except KeyError as e:
              raise TypeError(self.e_msg) from e
              start = f'$$ \beginbrackets'
              end = f'endbrackets $$
              '
              return "n".join([start, str(self), end])


              Which you can use like this:



              In [40]: x = np.random.rand(4, 5)

              In [41]: m = MathJaxMatrix(x)

              In [42]: print(m)
              0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
              0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
              0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
              0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448

              In [43]: print(f"m")
              $$beginmatrix
              0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
              0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
              0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
              0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
              endmatrix $$


              In [44]: print(f"m:p")
              $$beginpmatrix
              0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
              0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
              0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
              0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
              endpmatrix $$


              In [45]: print(f"m:a")
              $$ left[ beginarrayc
              0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
              0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
              0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
              0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
              endarray right] $$


              In [62]: print(f"m:e")
              ---------------------------------------------------------------------------
              KeyError Traceback (most recent call last)
              ...
              KeyError: 'e'

              The above exception was the direct cause of the following exception:

              TypeError Traceback (most recent call last)
              ...
              TypeError: unsupported format string passed to MathJaxMatrix.__format__


              Note that this removes the repeated code for getting a string representation of the actual matrix, uses np.ndarray.ndim and np.reshape to ensure it is a proper 2D matrix. I used the first letter of the different *matrix options to distinguish them because } is not allowed in format specifications.



              The actual convenience function is then quite short:



              def format_matrix(m, format_spec):
              m = MathJaxMatrix(m)
              s = f"m:format_spec"
              print(s)
              pyperclip.copy(s)





              share|improve this answer












              $endgroup$

















                9














                9










                9







                $begingroup$

                Python's string formatting has come a long way from the "%s" formatting days. Nowadays classes can even determine on their own how to handle format specifiers. Therefore I would write a matrix class that can be pretty printed with different format options determining the matrix style.



                class MathJaxMatrix:
                brackets = '': 'matrix',
                'p': 'pmatrix',
                'b': 'bmatrix',
                'B': 'Bmatrix',
                'v': 'vmatrix',
                'V': 'Vmatrix'
                e_msg = "unsupported format string passed to MathJaxMatrix.__format__"

                def __init__(self, m):
                if m.ndim == 1:
                m = m.reshape(len(m), 1)
                self.m = m
                self.rows, self.cols = m.shape

                def __str__(self):
                return "\\ n".join(" & ".join(str(x) for x in row) for row in self.m)

                def __format__(self, format_spec=None):
                if format_spec is None:
                return str(self)
                if format_spec == "a":
                format_spec = 'c'
                start = rf'$$left[ beginarrayformat_spec'
                end = r'endarray right]$$
                '
                else:
                try:
                brackets = self.brackets[format_spec]
                except KeyError as e:
                raise TypeError(self.e_msg) from e
                start = f'$$ \beginbrackets'
                end = f'endbrackets $$
                '
                return "n".join([start, str(self), end])


                Which you can use like this:



                In [40]: x = np.random.rand(4, 5)

                In [41]: m = MathJaxMatrix(x)

                In [42]: print(m)
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448

                In [43]: print(f"m")
                $$beginmatrix
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endmatrix $$


                In [44]: print(f"m:p")
                $$beginpmatrix
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endpmatrix $$


                In [45]: print(f"m:a")
                $$ left[ beginarrayc
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endarray right] $$


                In [62]: print(f"m:e")
                ---------------------------------------------------------------------------
                KeyError Traceback (most recent call last)
                ...
                KeyError: 'e'

                The above exception was the direct cause of the following exception:

                TypeError Traceback (most recent call last)
                ...
                TypeError: unsupported format string passed to MathJaxMatrix.__format__


                Note that this removes the repeated code for getting a string representation of the actual matrix, uses np.ndarray.ndim and np.reshape to ensure it is a proper 2D matrix. I used the first letter of the different *matrix options to distinguish them because } is not allowed in format specifications.



                The actual convenience function is then quite short:



                def format_matrix(m, format_spec):
                m = MathJaxMatrix(m)
                s = f"m:format_spec"
                print(s)
                pyperclip.copy(s)





                share|improve this answer












                $endgroup$



                Python's string formatting has come a long way from the "%s" formatting days. Nowadays classes can even determine on their own how to handle format specifiers. Therefore I would write a matrix class that can be pretty printed with different format options determining the matrix style.



                class MathJaxMatrix:
                brackets = '': 'matrix',
                'p': 'pmatrix',
                'b': 'bmatrix',
                'B': 'Bmatrix',
                'v': 'vmatrix',
                'V': 'Vmatrix'
                e_msg = "unsupported format string passed to MathJaxMatrix.__format__"

                def __init__(self, m):
                if m.ndim == 1:
                m = m.reshape(len(m), 1)
                self.m = m
                self.rows, self.cols = m.shape

                def __str__(self):
                return "\\ n".join(" & ".join(str(x) for x in row) for row in self.m)

                def __format__(self, format_spec=None):
                if format_spec is None:
                return str(self)
                if format_spec == "a":
                format_spec = 'c'
                start = rf'$$left[ beginarrayformat_spec'
                end = r'endarray right]$$
                '
                else:
                try:
                brackets = self.brackets[format_spec]
                except KeyError as e:
                raise TypeError(self.e_msg) from e
                start = f'$$ \beginbrackets'
                end = f'endbrackets $$
                '
                return "n".join([start, str(self), end])


                Which you can use like this:



                In [40]: x = np.random.rand(4, 5)

                In [41]: m = MathJaxMatrix(x)

                In [42]: print(m)
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448

                In [43]: print(f"m")
                $$beginmatrix
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endmatrix $$


                In [44]: print(f"m:p")
                $$beginpmatrix
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endpmatrix $$


                In [45]: print(f"m:a")
                $$ left[ beginarrayc
                0.35170079706 & 0.903087473471 & 0.748996998207 & 0.741200595894 & 0.771233795397\
                0.251204439922 & 0.40876741255 & 0.101668325527 & 0.738733484611 & 0.3052742949\
                0.448079803976 & 0.273533142438 & 0.368031240997 & 0.34312026244 & 0.587809084934\
                0.0192109217812 & 0.334069285732 & 0.644616319752 & 0.648226279564 & 0.307678962448
                endarray right] $$


                In [62]: print(f"m:e")
                ---------------------------------------------------------------------------
                KeyError Traceback (most recent call last)
                ...
                KeyError: 'e'

                The above exception was the direct cause of the following exception:

                TypeError Traceback (most recent call last)
                ...
                TypeError: unsupported format string passed to MathJaxMatrix.__format__


                Note that this removes the repeated code for getting a string representation of the actual matrix, uses np.ndarray.ndim and np.reshape to ensure it is a proper 2D matrix. I used the first letter of the different *matrix options to distinguish them because } is not allowed in format specifications.



                The actual convenience function is then quite short:



                def format_matrix(m, format_spec):
                m = MathJaxMatrix(m)
                s = f"m:format_spec"
                print(s)
                pyperclip.copy(s)






                share|improve this answer















                share|improve this answer




                share|improve this answer








                edited Oct 15 at 18:19

























                answered Oct 15 at 18:07









                GraipherGraipher

                31.8k6 gold badges50 silver badges108 bronze badges




                31.8k6 gold badges50 silver badges108 bronze badges































                    draft saved

                    draft discarded















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f230758%2fpython-algorithm-that-converts-array-like-data-into-mathjax%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown









                    Popular posts from this blog

                    Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                    Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                    199年 目錄 大件事 到箇年出世嗰人 到箇年死嗰人 節慶、風俗習慣 導覽選單