| 1 | | |
| 2 | | == General guidelines == |
| 3 | | |
| 4 | | - comment your code (everybody must understand what is being done) |
| 5 | | - NEVER more than one blank line please! |
| 6 | | - Align operators vertically to emphasize local program structure and semantics when possible |
| 7 | | - Do not use excessive blank spaces (especially in equations) |
| 8 | | |
| 9 | | == C/C++ == |
| 10 | | |
| 11 | | - if/for should follow this: |
| 12 | | - no space fetween if/for and its statement |
| 13 | | - If an if/for holds on one line, then do not use brackets |
| 14 | | - Otherwise, use brackets |
| 15 | | {{{ |
| 16 | | #!c |
| 17 | | for(int i=0<i<n;i++) A[i]=i; |
| 18 | | |
| 19 | | for(int i=0<i<n;i++){ |
| 20 | | A[i]=B[i]; |
| 21 | | B[i]=0; |
| 22 | | } |
| 23 | | |
| 24 | | if(a==0) bool=true; |
| 25 | | |
| 26 | | if(a==0) |
| 27 | | bool=true; |
| 28 | | else if(a==1) |
| 29 | | bool=flase; |
| 30 | | else |
| 31 | | _error_("a=%g not supported",a); |
| 32 | | |
| 33 | | if(a==0){ |
| 34 | | output=true; |
| 35 | | c=b |
| 36 | | } |
| 37 | | else{ |
| 38 | | output=false |
| 39 | | c=a; |
| 40 | | } |
| 41 | | }}} |
| 42 | | |
| 43 | | - Comments should follow the code indentation and there should not be any blank line between a comment and the code it is referring to |
| 44 | | {{{ |
| 45 | | #!c |
| 46 | | /*Assigning values of A*/ |
| 47 | | for(int i=0<i<n;i++){ |
| 48 | | |
| 49 | | /*The comment here is indented*/ |
| 50 | | A[i]=i; |
| 51 | | } |
| 52 | | }}} |
| 53 | | |
| 54 | | - Function declaration should hold on one line only |
| 55 | | {{{ |
| 56 | | #!c |
| 57 | | bool Test(int a,double b,char* c){ |
| 58 | | }}} |
| 59 | | == MATLAB == |
| 60 | | |
| 61 | | All MATLAB routines should start with a help (Example and See Also are not mandatory): |
| 62 | | {{{ |
| 63 | | #!m |
| 64 | | function outputs=FunctionName(inputs) |
| 65 | | %FUNCTIONNAME - one line description |
| 66 | | % |
| 67 | | % Extensive description of what is being done, inputs |
| 68 | | % outputs, etc... |
| 69 | | % |
| 70 | | % Usage: |
| 71 | | % outputs=FunctionName(inputs) |
| 72 | | % |
| 73 | | % Example: |
| 74 | | % md.test=FunctionName(1); |
| 75 | | % |
| 76 | | % See Also: |
| 77 | | % FunctionName2, FunctionName3, ... |
| 78 | | }}} |
| 79 | | |
| 80 | | At the very least, the first line and the Usage should be provided. Use indentations of 3 and 6 spaces. Example: |
| 81 | | |
| 82 | | {{{ |
| 83 | | #!m |
| 84 | | function outputs=hello() |
| 85 | | %HELLO - prints hello to the screen |
| 86 | | % |
| 87 | | % Usage: |
| 88 | | % outputs=hello() |
| 89 | | }}} |
| 90 | | |
| 91 | | === Vim Folding === |
| 92 | | Classes, functions, and other logical blocks of code should be folded (note the exact formatting used below): |
| 93 | | {{{ |
| 94 | | #!m |
| 95 | | function foo() % {{{ |
| 96 | | ... |
| 97 | | end % }}} |
| 98 | | }}} |
| 99 | | |
| 100 | | |
| 101 | | == Python == |
| 102 | | |
| 103 | | [https://www.python.org/dev/peps/pep-0008/ PeP8 compliance] should be used throughout the code with the exceptions below (with flake8 codes): |
| 104 | | - We allow lines of any length (E501) |
| 105 | | - We don't enforce the space after "#" for comments (E262, E265) |
| 106 | | - We still allow form module import * (F403) but we should avoid those if possible |
| 107 | | - We bypass warning on undefined function (F405) this can probably be removed if we take care of the one above |
| 108 | | flake8 allows you to track and highlight the syntax errors (through Elpy in Emacs, I guess it can be introduced in vim). |
| 109 | | |
| 110 | | If you install flake8, you can also run it in standalone to check the files in a directory: |
| 111 | | {{{ |
| 112 | | flake8 --ignore=E262,E265,F403,F405,E405,E501 |
| 113 | | }}} |
| 114 | | |
| 115 | | === Docstrings === |
| 116 | | Adhering to [https://www.python.org/dev/peps/pep-0257/ PEP8 Docstring Conventions] while attempting to mirror the conventions we follow under MATLAB, modules, functions, classes, and method definitions should be documented according to the following protocol: |
| 117 | | |
| 118 | | {{{ |
| 119 | | #!python |
| 120 | | def FunctionName(inputs): |
| 121 | | """FunctionName - one line description |
| 122 | | |
| 123 | | Extensive description of what is being done, inputs |
| 124 | | outputs, etc... |
| 125 | | |
| 126 | | Usage: |
| 127 | | outputs = FunctionName(inputs) |
| 128 | | |
| 129 | | Example: |
| 130 | | md.test = FunctionName(1) |
| 131 | | |
| 132 | | See Also: |
| 133 | | FunctionName2, FunctionName3, ... |
| 134 | | """ |
| 135 | | }}} |
| 136 | | |
| 137 | | As with MATLAB, at the very least, the first line and the 'Usage' should be provided. Unlike MATLAB, use indentations of 4 and 8 spaces. |
| 138 | | |
| 139 | | === Vim Folding === |
| 140 | | Classes, functions, and other logical blocks of code should be folded (note the exact formatting used below): |
| 141 | | {{{ |
| 142 | | #!python |
| 143 | | def foo(): # {{{ |
| 144 | | ... |
| 145 | | # }}} |
| 146 | | }}} |
| 147 | | |
| 148 | | === MATLAB Built-In Equivalents === |
| 149 | | The following is a list of MATLAB built-in equivalents in Python: |
| 150 | | ||= '''MATLAB''' =||= '''Python''' =||= '''Notes''' =|| |
| 151 | | || `s=num2str(A)` || `s=str(A)` || convert numbers to character array || |
| 152 | | |
| 153 | | === !NumPy/SciPy === |
| 154 | | !NumPy and !SciPy are used extensively in the Python interface to ISSM to replicate MATLAB-native functionality. When translating modules or tests, for example, from MATLAB to Python, the following sources may come in handy: |
| 155 | | - [https://numpy.org/devdocs/user/numpy-for-matlab-users.html NumPy for Matlab users | NumPy] |
| 156 | | - [http://mathesaurus.sourceforge.net/matlab-numpy.html NumPy for MATLAB users | mathesaurus.sourceforge.net] |
| 157 | | Some notable omissions in the above sources are as follows: |
| 158 | | ||= '''MATLAB''' =||= '''!NumPy''' =||= '''Notes''' =|| |
| 159 | | || `<<cell_array>>{:}` || `<<np.ndarray>>.flatten()` || Flatten a MATLAB cell array or !NumPy `ndarray`. || |
| 160 | | || `find(a>0.5)` || `np.where(a>0.5)[0]` || Find the indices where (a > 0.5).[[BR]][[BR]]When only the {{{condition}}} parameter is provided, this function is a shorthand for `np.asarray(condition).nonzero()`.[[BR]][[BR]]See also: [https://numpy.org/doc/stable/reference/generated/numpy.where.html numpy.where - NumPy][[BR]][[BR]]NOTE:[[BR]]- `a` must be of type `np.array` (or one of its subclasses): a {{{list}}} will not automatically be cast.[[BR]]- Returns a tuple of arrays of indices, one for each dimension of the input array. Thus, when the input array is 1D, the indices can be retrieved simply by addressing the first element of the result (as in the example). || |
| 161 | | || `find('cond1'&'cond2')` || `np.where(np.logical_and.reduce(('cond1','cond2'))[0]` || Find the indices where `'cond1'` and `'cond2'` are met.[[BR]][[BR]]The same protocol can be followed for MATLAB's `|` by instead using `logical_or`.[[BR]][[BR]]More than two conditions may be compounded. || |
| 162 | | || `v=nonzeros(A)` || `v=A[np.nonzero(A)]` || Find the values of the nonzero elements || |
| 163 | | || `B=sortrows(A,column)` || `B=A[A[:,column].argsort()]` || sort rows of matrix or table (MATLAB), or 2D array (!NumPy) in ascending order based on the elements in 'column' || |
| 164 | | || `sqrt(A)` || `A ** 0.5` || Element-wise square root (math.sqrt can only be applied to scalars) || |
| 165 | | |
| 166 | | == !Variable/Enum/Function Names == |
| 167 | | |
| 168 | | - variables should not use capital letters. Use underscores to make variables more understandable. |
| 169 | | |
| 170 | | - Function names and enums should not use any underscore. Use capital letters to make names more understandable. |
| 171 | | Example: |
| 172 | | {{{ |
| 173 | | #!c |
| 174 | | Input* vx_input=GetInput(inputs,VxInput); |
| 175 | | }}} |
| | 1 | Migrated to [https://issmteam.github.io/ISSM-Documentation/using-issm/miscellaneous/codeguidelines] |