Name | motopy JSON |
Version |
2.1.0
JSON |
| download |
home_page | |
Summary | The tool of converting Matlab/Octave code TO PYthon. |
upload_time | 2023-02-06 06:25:46 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.7 |
license | |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Motopy
`Motopy` is a tool used to translate Matlab/Octave code TO PYthon.
[点此查看中文说明](https://github.com/falwat/motopy/blob/main/readme_zh.md).
## Introduce
`Motopy` is a powerful tool used to translate `Matlab`/`Octave` code to `PYthon`. In the process of translation, the python statement generated by `mopy` will be executed to ensure the translated correctness of subsequent code. For example, the following `Matlab`/`Octave` code:
```m
a = ones(1, 3);
b = a';
c = a * b;
```
will be translated to `python` code:
```py
import numpy as np
a = np.ones((1, 3))
b = a.T
c = a @ b
```
The type of the variables `a` and `b` are array. So the third statement `c = a * b` will be translate to: `c = a @ b`.
## install
Please use `pip` install `motopy`:
```bash
pip install motopy
```
## Quick Start
`Motopy` is very easy to use. First please prepare your `Matlab`/`Octave` files, put the script file and the function files with extetion ".m" in a folder, and ensure that your `Matlab`/`Octave` script can be run without exception. And meet [Code Preprocessing](#Code_Preprocessing).Here's a simple example:
- Create a folder named "demo".
- In the "demo" folder, create two ".m" files whose names are "fun.m" and "func_test.m". Input the folowing text:
```m
% file: func.m
function s = func(a, b)
s = sqrt(a.^2 + b.^2);
end
```
```m
% file: func_test.m
a = 3;
b = 4;
s = func(a, b);
disp(s)
```
- In the "demo" folder, create a `python` script file. Import `motopy` and use `motopy.make()` translate your mfile:
```py
import motopy
motopy.make(entry_basename='func_test')
```
The `entryfile` parameter specifies the mfile script to be translated(***!!Note that there is no extension!! ***).
> You can also execute the above code directly from the python command line. Ensure that the current directory is the "demo" folder.
### Specify the input/output folder
The `python` script file may not be placed in the same folder as the mfile, and the input mfile and the output `python` file may be in a different folder. You can use the `input_path` parameter to specify the location of the input mfile and the `output_path` parameter to specify the output path of the generated `python` file.
```py
import motopy
motopy.make(
entry_basename='<the script filename without extension(*.m)>',
input_path='<the input path of *.m files>',
output_path='<the output path of *.py files>'
)
```
### Specify replaced function
If you have already translated a function, you can specify an replaced function to that function using the `replaced_functions` argument in the `motopy.make()` function.
```py
import motopy
motopy.make(
entry_basename='func_test', # no extension
input_path='The path that input ".m" files loaded',
output_path='The path that output ".py" files stored',
replaced_functions={
'func': ('func', 'func') #
}
)
```
The `replaced_functions` parameter is a dictionary, the key is the function name that appears in the mfile, and the value is a tuple (`module_name`, `function_name`). In the example above, the `func` function file will not be translated again.
When do you use `replaced_functions`:
- The `.py` file generated by `motopy` has been modified manually, and do not want `motopy` to regenerate it.
- The `.m` function that `motpy` does not support translated yet. You can implement it by yourself.
### Code Annotation
The code line started with "`%%>`" in mfile is a python statment. And will be inserted to generated `python` file. And the next statment will be skiped. For example, the mfile:
```m
%%> print('this is a code annotation.')
disp('this statment will be skiped.')
```
will be translated to:
```py
print('this is a code annotation.')
```
### Output Log
By default, `motopy` generate a log file named "motopy.log" under the `output_path` folder. You can use the 'logging_file' parameter to specify the output location and name of the log file. Using `logging_level` set log level: `WARN|INFO|DEBUG`
```py
import motopy
motopy.make(.., logging_level=motopy.DEBUG, ..)
```
### Indent
By default, the generated `.py` file uses 4 Spaces for indentation. You can use `indent` parameter specifies the number of Spaces required for indentation.
## Code Preprocessing
The translation will failed if your `Matlab`/`Octave` code don't satisfy the folowing requirements:
- Do not use blank spaces to separate elements in arrays and cells. The following code will make failed:
```m
a = [1 2 3; 4 5 6];
c = {1 2 'abc'};
```
- The first function name in a function file must be same as the filename.
- Arrays and cells should be defined before used and allocated enough space. The following code will make failed:
```m
for k=1:5
A(k) = 2*k; % The variable A is not defined before used.
end
```
```m
A = []; % The variable A has not enough space.
for k=1:5
A(k) = 2*k; % the size of variable A will grow in iteration.
end
```
- Do not use "`[]`" to define empty array. The folowing mcode will translate failed:
```m
A = [];
for k=1:5
B= rand(2,2);
A = [A;B];
end
disp(A)
```
The expression `[A;B]` translate failed. because the empty array A with size of `0x0` cannot concatenate with array B with size of `2x2`.
An easy way to resolve this problem is to define the array `A` as an empty array with size of `0x2`:
```m
A = zeros(0,2);
for k=1:5
B= rand(2,2);
A = [A;B];
end
disp(A)
```
## Implemented Translation
### Creation of Array, Matrix and Cell
Matlab/Octave|Python|Note
-|-|-
`a = [1,2,3,4]` | `a = np.array([1, 2, 3, 4])` | The array in `matlab` will be translated to `np.array`
`a = [1,2;3,4]` | `a = np.array([[1, 2], [3, 4]])`
`a = [1;2;3;4]` | `a = np.array([[1], [2], [3], [4]])`
`C = {1,2,3;'4',[5,6],{7,8,9}}` | `C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]]` | The cell in `matlab` will be translated to `list`
`r1 = 1:10;` | `r1 = arange(1, 11)` | `low_bound:high_bound` in `matlab` will be translated to `arange(low_bound, high_boud + 1)`
`N = 10;`<br>`r2 = 1:N;` | `N = 10`<br>`r2 = arange(1, N + 1)`
`zeros(3)` | `np.zeros((3, 3))`
`zeros(2,3)` | `np.zeros((2, 3))`
`ones(3)` | `np.ones((3, 3))`
`ones((2, 3))` | `np.ones((2, 3))`
`C = cell(2,3)` | `C = [[None for _c in range(3)] for _r in range(2)]`
### Slice of Array, Matrix and Cell
Matlab/Octave|Python|Note
-|-|-
`a(1,1)` | `a[0, 0]` | The value of `index` will decrease 1, if the `index` is a number.
`a(1,:)` | `a[0, :]`
`a(:,1)` | `a[:, 0]`
`a(1, 1:2)` | `a[0, 0:2]`
`a(1:2, 1)` | `a[0:2, 0]`
`a(1,2:end)` | `a[0, 1:]`
`m = 1;`<br>`n = 1;`<br>`a(m, n*2)` | `m = 1`<br>`n = 1`<br>`a[m - 1, n * 2 - 1]` | The `index` will be replaced with `index - 1`, if `index` is a variable.
### Functions
Matlab/Octave|Python|Note
-|-|-
`abs` | `np.abs`
`acos` | `np.arccos`
`asin` | `np.arcsin`
`atan` | `np.arctan`
`[y,Fs] = audioread(filename)` | `Fs, y = wavfile.read(filename)`
`ceil` | `np.ceil`
`cos` | `np.cos`
`diag` | `np.diag`
`d = dir(name)` | `d = [{'name':e.name, 'folder':e.path, 'isdir':e.is_dir()} for e in scandir(name)]`
`disp` | `print`
`eye` | `np.eye`
`exp` | `np.exp`
`fft` | `np.fft`
`fix` | `np.fix`
`floor` | `np.floor`
`fprintf` |
`ifft` | `np.ifft`
`inv` | `linalg.inv`
`linspace` | `np.linspace`
`S = load('data.mat')`| `S = loadmat('data.mat')` | the Variable `S` is a dict
`A = load('data.txt')` | `A = np.loadtxt('data.txt')` | the file "data.txt" is a ASCII data.
`load('data.mat')` | `_mat = loadmat('data.mat');`<br>`a = _mat['a'];`<br>`b = _mat['b']` | assume there are two variable `a` and `b` in "data.mat"
`load('data.txt')` | `data = np.loadtxt('data.txt')` | the file "data.txt" is a ASCII data.
`log` | `np.log`
`log10` | `np.log10`
`log2` | `np.log2`
`mod` | `np.mod`
`ndims` | `np.ndim`
`numel` | `np.size`
`pinv` | `linalg.pinv`
`rand` | `random.rand`
`rank` | `linalg.matrix_rank`
`round` | `np.round`
`sin` | `np.sin`
`sort` | `np.sort`
`sprintf('%d%s',a, b)` | `f'{a}{b}'`
`sqrt` | `np.sqrt`
`s = strcat(s1,...,sN)` | `s = ''.join([s1,...,sN])`
`unique` | `np.unique`
## Change Log
See [changelog.md](https://github.com/falwat/motopy/blob/main/changelog.md) for more information.
Raw data
{
"_id": null,
"home_page": "",
"name": "motopy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "",
"author_email": "Jackie Wang <falwat@163.com>",
"download_url": "https://files.pythonhosted.org/packages/06/6a/915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7/motopy-2.1.0.tar.gz",
"platform": null,
"description": "# Motopy\n\n`Motopy` is a tool used to translate Matlab/Octave code TO PYthon.\n\n[\u70b9\u6b64\u67e5\u770b\u4e2d\u6587\u8bf4\u660e](https://github.com/falwat/motopy/blob/main/readme_zh.md).\n\n## Introduce\n\n`Motopy` is a powerful tool used to translate `Matlab`/`Octave` code to `PYthon`. In the process of translation, the python statement generated by `mopy` will be executed to ensure the translated correctness of subsequent code. For example, the following `Matlab`/`Octave` code:\n\n```m\na = ones(1, 3);\nb = a';\nc = a * b;\n```\nwill be translated to `python` code:\n\n```py\nimport numpy as np\na = np.ones((1, 3))\nb = a.T\nc = a @ b\n```\n\nThe type of the variables `a` and `b` are array. So the third statement `c = a * b` will be translate to: `c = a @ b`.\n\n## install\n\nPlease use `pip` install `motopy`:\n\n```bash\npip install motopy\n```\n\n## Quick Start\n\n`Motopy` is very easy to use. First please prepare your `Matlab`/`Octave` files, put the script file and the function files with extetion \".m\" in a folder, and ensure that your `Matlab`/`Octave` script can be run without exception. And meet [Code Preprocessing](#Code_Preprocessing).Here's a simple example:\n- Create a folder named \"demo\".\n- In the \"demo\" folder, create two \".m\" files whose names are \"fun.m\" and \"func_test.m\". Input the folowing text:\n\t```m\n\t% file: func.m\n\tfunction s = func(a, b)\n\t s = sqrt(a.^2 + b.^2);\n\tend\n\t```\n\n\t```m\n\t% file: func_test.m\n\ta = 3;\n\tb = 4;\n\ts = func(a, b);\n\tdisp(s)\n\t```\n- In the \"demo\" folder, create a `python` script file. Import `motopy` and use `motopy.make()` translate your mfile:\n ```py\n import motopy\n motopy.make(entry_basename='func_test')\n ```\n The `entryfile` parameter specifies the mfile script to be translated(***!!Note that there is no extension!! ***).\n > You can also execute the above code directly from the python command line. Ensure that the current directory is the \"demo\" folder.\n\n### Specify the input/output folder\n\nThe `python` script file may not be placed in the same folder as the mfile, and the input mfile and the output `python` file may be in a different folder. You can use the `input_path` parameter to specify the location of the input mfile and the `output_path` parameter to specify the output path of the generated `python` file.\n```py\nimport motopy\n\nmotopy.make(\n entry_basename='<the script filename without extension(*.m)>',\n input_path='<the input path of *.m files>', \n output_path='<the output path of *.py files>' \n)\n```\n\n### Specify replaced function\n\nIf you have already translated a function, you can specify an replaced function to that function using the `replaced_functions` argument in the `motopy.make()` function.\n\n```py\nimport motopy\nmotopy.make(\n entry_basename='func_test', # no extension\n input_path='The path that input \".m\" files loaded', \n output_path='The path that output \".py\" files stored',\n replaced_functions={\n 'func': ('func', 'func') # \n }\n)\n```\n\nThe `replaced_functions` parameter is a dictionary, the key is the function name that appears in the mfile, and the value is a tuple (`module_name`, `function_name`). In the example above, the `func` function file will not be translated again.\n\nWhen do you use `replaced_functions`:\n\n- The `.py` file generated by `motopy` has been modified manually, and do not want `motopy` to regenerate it.\n\n- The `.m` function that `motpy` does not support translated yet. You can implement it by yourself.\n\n### Code Annotation\n\nThe code line started with \"`%%>`\" in mfile is a python statment. And will be inserted to generated `python` file. And the next statment will be skiped. For example, the mfile:\n\n```m\n%%> print('this is a code annotation.')\ndisp('this statment will be skiped.')\n```\nwill be translated to:\n```py\nprint('this is a code annotation.')\n```\n\n\n\n### Output Log\n\nBy default, `motopy` generate a log file named \"motopy.log\" under the `output_path` folder. You can use the 'logging_file' parameter to specify the output location and name of the log file. Using `logging_level` set log level: `WARN|INFO|DEBUG`\n\n```py\nimport motopy\nmotopy.make(.., logging_level=motopy.DEBUG, ..)\n```\n\n### Indent\n\nBy default, the generated `.py` file uses 4 Spaces for indentation. You can use `indent` parameter specifies the number of Spaces required for indentation.\n\n## Code Preprocessing\n\nThe translation will failed if your `Matlab`/`Octave` code don't satisfy the folowing requirements:\n\n- Do not use blank spaces to separate elements in arrays and cells. The following code will make failed:\n\n ```m\n a = [1 2 3; 4 5 6];\n c = {1 2 'abc'};\n ```\n\n- The first function name in a function file must be same as the filename.\n\n- Arrays and cells should be defined before used and allocated enough space. The following code will make failed:\n\n ```m\n for k=1:5\n A(k) = 2*k; % The variable A is not defined before used.\n end\n ```\n\n ```m\n A = []; % The variable A has not enough space.\n for k=1:5\n A(k) = 2*k; % the size of variable A will grow in iteration.\n end\n ```\n\n- Do not use \"`[]`\" to define empty array. The folowing mcode will translate failed:\n ```m\n A = [];\n for k=1:5\n B= rand(2,2);\n A = [A;B];\n end\n disp(A)\n ```\n The expression `[A;B]` translate failed. because the empty array A with size of `0x0` cannot concatenate with array B with size of `2x2`.\n\n An easy way to resolve this problem is to define the array `A` as an empty array with size of `0x2`:\n\n ```m\n A = zeros(0,2);\n for k=1:5\n B= rand(2,2);\n A = [A;B];\n end\n disp(A)\n ```\n\n## Implemented Translation\n\n### Creation of Array, Matrix and Cell \n\nMatlab/Octave|Python|Note\n-|-|-\n`a = [1,2,3,4]` | `a = np.array([1, 2, 3, 4])` | The array in `matlab` will be translated to `np.array`\n`a = [1,2;3,4]` | `a = np.array([[1, 2], [3, 4]])`\n`a = [1;2;3;4]` | `a = np.array([[1], [2], [3], [4]])`\n`C = {1,2,3;'4',[5,6],{7,8,9}}` | `C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]]` | The cell in `matlab` will be translated to `list`\n`r1 = 1:10;` | `r1 = arange(1, 11)` | `low_bound:high_bound` in `matlab` will be translated to `arange(low_bound, high_boud + 1)`\n`N = 10;`<br>`r2 = 1:N;` | `N = 10`<br>`r2 = arange(1, N + 1)`\n`zeros(3)` | `np.zeros((3, 3))`\n`zeros(2,3)` | `np.zeros((2, 3))`\n`ones(3)` | `np.ones((3, 3))`\n`ones((2, 3))` | `np.ones((2, 3))`\n`C = cell(2,3)` | `C = [[None for _c in range(3)] for _r in range(2)]`\n\n### Slice of Array, Matrix and Cell \nMatlab/Octave|Python|Note\n-|-|-\n`a(1,1)` | `a[0, 0]` | The value of `index` will decrease 1, if the `index` is a number.\n`a(1,:)` | `a[0, :]`\n`a(:,1)` | `a[:, 0]`\n`a(1, 1:2)` | `a[0, 0:2]`\n`a(1:2, 1)` | `a[0:2, 0]`\n`a(1,2:end)` | `a[0, 1:]`\n`m = 1;`<br>`n = 1;`<br>`a(m, n*2)` | `m = 1`<br>`n = 1`<br>`a[m - 1, n * 2 - 1]` | The `index` will be replaced with `index - 1`, if `index` is a variable.\n\n### Functions\n\nMatlab/Octave|Python|Note\n-|-|-\n`abs` | `np.abs`\n`acos` | `np.arccos`\n`asin` | `np.arcsin`\n`atan` | `np.arctan`\n`[y,Fs] = audioread(filename)` | `Fs, y = wavfile.read(filename)`\n`ceil` | `np.ceil`\n`cos` | `np.cos`\n`diag` | `np.diag`\n`d = dir(name)` | `d = [{'name':e.name, 'folder':e.path, 'isdir':e.is_dir()} for e in scandir(name)]`\n`disp` | `print`\n`eye` | `np.eye`\n`exp` | `np.exp`\n`fft` | `np.fft`\n`fix` | `np.fix`\n`floor` | `np.floor`\n`fprintf` | \n`ifft` | `np.ifft`\n`inv` | `linalg.inv`\n`linspace` | `np.linspace`\n`S = load('data.mat')`| `S = loadmat('data.mat')` | the Variable `S` is a dict \n`A = load('data.txt')` | `A = np.loadtxt('data.txt')` | the file \"data.txt\" is a ASCII data.\n`load('data.mat')` | `_mat = loadmat('data.mat');`<br>`a = _mat['a'];`<br>`b = _mat['b']` | assume there are two variable `a` and `b` in \"data.mat\"\n`load('data.txt')` | `data = np.loadtxt('data.txt')` | the file \"data.txt\" is a ASCII data.\n`log` | `np.log`\n`log10` | `np.log10`\n`log2` | `np.log2`\n`mod` | `np.mod`\n`ndims` | `np.ndim`\n`numel` | `np.size`\n`pinv` | `linalg.pinv`\n`rand` | `random.rand`\n`rank` | `linalg.matrix_rank`\n`round` | `np.round`\n`sin` | `np.sin`\n`sort` | `np.sort`\n`sprintf('%d%s',a, b)` | `f'{a}{b}'`\n`sqrt` | `np.sqrt`\n`s = strcat(s1,...,sN)` | `s = ''.join([s1,...,sN])`\n`unique` | `np.unique`\n\n## Change Log\n\nSee [changelog.md](https://github.com/falwat/motopy/blob/main/changelog.md) for more information.\n",
"bugtrack_url": null,
"license": "",
"summary": "The tool of converting Matlab/Octave code TO PYthon.",
"version": "2.1.0",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "beb64ef65d94ca145481fde756bf9baa863d183854f7d82d4ba81ae72484e783",
"md5": "e5fcbc07ff6a27ba64c00f630b3e4277",
"sha256": "786ff1a012186e53e746eab98b4d09a7665f9d30434e45279aa3ec13b34dac95"
},
"downloads": -1,
"filename": "motopy-2.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e5fcbc07ff6a27ba64c00f630b3e4277",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 24839,
"upload_time": "2023-02-06T06:25:44",
"upload_time_iso_8601": "2023-02-06T06:25:44.268388Z",
"url": "https://files.pythonhosted.org/packages/be/b6/4ef65d94ca145481fde756bf9baa863d183854f7d82d4ba81ae72484e783/motopy-2.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "066a915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7",
"md5": "44e2fafd2ff6492d923c7a1dfd3449c9",
"sha256": "2009fcb6c7a786cc39cc47acbc6c86c0ec8b7a7ac3cb64f020131970c568487a"
},
"downloads": -1,
"filename": "motopy-2.1.0.tar.gz",
"has_sig": false,
"md5_digest": "44e2fafd2ff6492d923c7a1dfd3449c9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 31803,
"upload_time": "2023-02-06T06:25:46",
"upload_time_iso_8601": "2023-02-06T06:25:46.342899Z",
"url": "https://files.pythonhosted.org/packages/06/6a/915d2e150b7185b61f53ec9df00b0b526f50725c07a3178179843ca3eaa7/motopy-2.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-02-06 06:25:46",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "motopy"
}